无专精则不能|

伍六柒-

园龄:3年6个月粉丝:9关注:6

CodeForces#752div2_A-D

A-Era

题目描述

Shohag有一个整数数列 a1,a2,a3......,an,他可以执行以下操作任意次数(也可能是0次):

    1. 选择任意一个整数 k (在不同的操作中它可以是不同的)
    1. 在这个数列中选择任意一个位置,并把 k 插入到这个位置
    1. 通过这种方式,这个数列就被改变了,接下来的操作是在改变之后的数列上完成的

例如,如果 a = [3,3,4],选择的 k = 2,再一次操作之后,他可以得到[2,3,3,4],[3,2,3,4],[3,3,2,4],[3,3,4,2]中的一个。Shohag想让这个数列满足以下情况:对于每一个 1 <= i <= a,ai <= i。这里的a是指数列的大小。

帮助他找到最小的操作次数,使他能达到目标。我们可以证明,在限制条件下总能找到可能的方式去达到目标。
输入描述
第一行是一个整数 t ,代表测试样例的个数
每组测试样例的第一行是一个整数 n 代表最初的数列长度
每组测试样路的第二行是 n 个整数,代表这个数列的每个元素
原题链接


Input

4
3
1 3 4
5
1 2 5 7 4
1
1
3
69 6969 696969

Output

1
3
0
696966

解题思路


用一个 ans 来统计结果,从第一个元素开始往后遍历,遍历到第 j 位时,如果 aj > j + ans,则 ans += aj - (j + ans)即 ans = aj - j,遍历完整个数组后得到的 ans 即是结果,记得初始化 ans = 0


AC代码

#include <iostream>
using namespace std;
const int N = 110;
int t,n,arr[N],ans,cnt;
int main() {
cin >> t;
while(t--) {
ans = 0;
cin >> n;
for(int i = 1; i <= n; i++) cin >> arr[i];
for(int i = 1; i <= n; i++) {
if(arr[i] > i + ans) { // i + ans 表示前面插入了 ans 个数之后原来的 i 变成了 i + ans
ans = arr[i] - i;
}
}
cout << ans << endl;
}
return 0;
}

B-XOR Specia-LIS-t

题目描述


Input

4
7
1 3 4 2 2 1 5
3
1 3 4
5
1 3 2 4 2
4
4 3 2 1

Output

YES
NO
YES
YES

题解思路


对于一组数列,我们可以找到一种特殊的分组方式,即把每个元素当成一组,这样每组的升序值就是1,如果 n 是偶数的话,异或结果刚好为 0 ,当 n 为奇数时,结果为 1,显然不行,我们可以想,怎样才能使分出来的组数刚好为偶数,而且每组的升序值都是 1 呢?不难发现,如果两个数为一组,[a,b],当 a >= b 时升序值为 1,而且刚好凑成了偶数个分组。如果 n 为奇数,数列又不是绝对升序的,那么按照刚刚的分组方式,一定能使最后的异或值等于 0,如果是绝对升序的,一定找不到。


AC代码

#include <iostream>
#include <map>
using namespace std;
int t,n,cnt,a,b;
bool flag;
int main() {
cin >> t;
while(t--) {
b = -1;
flag = false;
cin >> n;
for(int i = 0; i < n; i++){
cin >> a;
if(a > b) b = a;
else flag = true;
}
if(flag || n % 2 == 0)puts("YES");
else puts("NO");
}
return 0;
}

C-Di-visible Confusion

题目描述


YKW 有一个整数数列 a1,a2,a3......,an,他将执行以下操作直至这个序列成为空序列:选择一个下标为 i 的元素,如果满足 1 <= i <= |a| 并且 ai 不能被(i + 1)整除,就从这个序列中删掉这个元素。在这里|a|表示此刻序列的长度。注意,如果序列 a 被改变了,则接下来的操作是在改变后的 a 序列上实现的。

比如,如果 a = [3,5,4,5],然后选择 i = 2,因为 a2 不能被 i+1 = 3整除。在这个操作之后这个序列变成了[3,4,5]
YKW 想弄清楚是否可能通过上述的操作使这个序列清空。
输入描述
第一行包含一个整数 t 代表测试样例的个数
对于每一组测试样例的第一行是一个整数 n
每组测试样例的第二行是 n 个整数 a1,a2,a3,......an
保证所有样例的 n 之和不超过 3e5


Input

5
3
1 2 3
1
2
2
7 7
10
384836991 191890310 576823355 782177068 404011431 818008580 954291757 160449218 155374934 840594328
8
6 69 696 69696 696969 6969696 69696969 696969696

Output

YES
NO
YES
YES
NO

解题思路


如果 ai 能被删除,那么它一定是因为不能整除 2,3...,i+1中的某一个或多个,被删除的,如果它能整除 2,3...,i+1中的任何一项,那么它一定无法被删除,如何判断它能不能整除所有的数呢?最小公倍数。如果它能整除2,3...,i+1的最小公倍数那么它也一定能整除所有的数,否则一定存在一个数,它不能整除,就在那个位置将它删除就行。如果ai前面的所有数都能被删除,(如果ai存在一个在[2,i+1]的值使它不能整除)那么ai 一定也能被删除,因为前面的都可以被删除,所有它一定可以到达[1,i]的所有位置。所以,我们只需要遍历一边数组,判断每一个能不能被删除,如果有不能被删除的,则直接跳出,输出结果 NO,否则输出 YES。由于测试样例很多,我们需要先预处理出来所有[2,i+1]的最小公倍数,存入lcm数组中,不难发现,当 i+1 = 23时,lcm[i+1]已经超出了1e9,由于 ai <= 1e9所以,当 i+1 > 23时ai一定能被删除。上代码。


AC代码

#include <iostream>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int gcd (int a,int b) {
if(b == 0) return a;
else return gcd(b, a % b);
}
int LCM (int a,int b){ //返回a,b的最小公倍数
if(a < b) swap(a,b);
return a * b / gcd(a,b);
}
int t,n,arr[N],lcm[25];
bool flag;
signed main () {
cin >> t;
lcm[1] = 1;
for(int i = 2; i <= 23; i++) //递推求[2,i+1]的最小公倍数
lcm[i] = LCM(i,lcm[i-1]);
// for(int i = 1; i <= 23; i++) cout << lcm[i] << " ";
while(t--) {
flag = true;
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> arr[i];
if(i <= 21 && arr[i] % lcm[i + 1] == 0) flag = false;
}
if(flag) puts("YES");
else puts("NO");
}
return 0;
}

D-Moderate Modular Mode

直接上代码

AC代码

#include <iostream>
#define int long long
using namespace std;
int t,x,y,n;
signed main(){
cin >> t;
while(t--) {
cin >> x >> y;
if(x > y) n = x + y;
else if(x == y) n = x;
else n = y - y % x / 2;
cout << n << endl;
}
return 0;
}

本文作者:伍六柒-

本文链接:https://www.cnblogs.com/paper-plane/p/15497970.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   伍六柒-  阅读(105)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开