CodeForces#752div2_A-D
A-Era
题目描述
Shohag有一个整数数列 ,,......,,他可以执行以下操作任意次数(也可能是0次):
- 选择任意一个整数 k (在不同的操作中它可以是不同的)
- 在这个数列中选择任意一个位置,并把 k 插入到这个位置
- 通过这种方式,这个数列就被改变了,接下来的操作是在改变之后的数列上完成的
例如,如果 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, <= 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 位时,如果 > j + ans,则 ans += - (j + ans)即 ans = - 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 有一个整数数列 ,,......,,他将执行以下操作直至这个序列成为空序列:选择一个下标为 i 的元素,如果满足 1 <= i <= |a| 并且 不能被(i + 1)整除,就从这个序列中删掉这个元素。在这里|a|表示此刻序列的长度。注意,如果序列 a 被改变了,则接下来的操作是在改变后的 a 序列上实现的。
比如,如果 a = [3,5,4,5],然后选择 i = 2,因为 不能被 i+1 = 3整除。在这个操作之后这个序列变成了[3,4,5]
YKW 想弄清楚是否可能通过上述的操作使这个序列清空。
输入描述
第一行包含一个整数 t 代表测试样例的个数
对于每一组测试样例的第一行是一个整数 n
每组测试样例的第二行是 n 个整数 ,,,......
保证所有样例的 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
解题思路
如果 能被删除,那么它一定是因为不能整除 2,3...,i+1中的某一个或多个,被删除的,如果它能整除 2,3...,i+1中的任何一项,那么它一定无法被删除,如何判断它能不能整除所有的数呢?最小公倍数。如果它能整除2,3...,i+1的最小公倍数那么它也一定能整除所有的数,否则一定存在一个数,它不能整除,就在那个位置将它删除就行。如果前面的所有数都能被删除,(如果存在一个在[2,i+1]的值使它不能整除)那么 一定也能被删除,因为前面的都可以被删除,所有它一定可以到达[1,i]的所有位置。所以,我们只需要遍历一边数组,判断每一个能不能被删除,如果有不能被删除的,则直接跳出,输出结果 NO,否则输出 YES。由于测试样例很多,我们需要先预处理出来所有[2,i+1]的最小公倍数,存入lcm数组中,不难发现,当 i+1 = 23时,lcm[i+1]已经超出了1e9,由于 <= 1e9所以,当 i+1 > 23时一定能被删除。上代码。
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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步