Codeforces Round #630 (Div. 2)
A. Exercising Walk (CF 1332 A)
题目大意
给定初始坐标。有次向左走,有次向右走,有次向下走,有次向上走。给定,问是否存在一种走的序列,使得坐标始终满足。
解题思路
判断即可。
特别地当的时候还要判断是否同为,同理。
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; int main(void) { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin>>t; while(t--){ LL a,b,c,d,x,y,x1,y1,x2,y2; cin>>a>>b>>c>>d>>x>>y>>x1>>y1>>x2>>y2; LL xx=x+(b-a); LL yy=y+(d-c); bool qwq=0; if (xx>=x1&&xx<=x2&&yy>=y1&&yy<=y2) qwq=true; if (x1==x2&&(b!=0||a!=0)) qwq=false; if (y1==y2&&(c!=0||d!=0)) qwq=false; if (qwq) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
B. Composite Coloring (CF 1332 B)
题目大意
组询问,每组询问给定个合数,要求对个数进行涂色,颜色数不超过,要求相同颜色的任意两个数的最大公因数大于。输出一种可行涂色方案,不要求最小化颜色数。保证有解。
解题思路
由于且为合数,得知的因数中至少有一个小于的质数,因为如果都大于的话,会有与矛盾。而刚好是第个质数,所以我们就看一个数最小质数是多少给它涂上相应的颜色就就好了。
(此处直接暴力)
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int t; read(t); while(t--){ int n; read(n); int qwq[1005]={0}; int ans[1005]={0}; int cnt=0; for(int u,i=1;i<=n;++i){ read(u); int up=sqrt(u); bool qaq=false; int tmp=u; for(int j=2;j<u;++j){ if (u%j==0){ if (qwq[j]) { ans[i]=qwq[j]; qaq=true; break; } else if (tmp==u) tmp=j; } } if (!qaq) ans[i]=qwq[tmp]=++cnt; } write(cnt,'\n'); for(int i=1;i<=n;++i){ printf("%d%c",ans[i],i==n?'\n':' '); } } return 0; }
C. K-Complete Word (CF 1332 C)
题目大意
给定一个只包含小写字母的字符串及一个数字,每次操作可以拿任意一个小写字母替换一个位置的上的小写字母。要求最小化操作次数,使得字符串变成
- 是个回文串
解题思路
目标串是一个由前缀串长度为的重复次得到的。由于,类似的等式可以证明这个长度为的前缀串也是个回文串。那么对于每个重复串,每个从到位,它们对应的字母一共有个,我们取出现次数最多的字母作为这个位的字母,这样保留的字母就尽可能的多,替换的操作就尽可能的少了。
为奇数的时候中间那个位的字母就只有个。
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int t; read(t); while(t--){ int n,k; read(n); read(k); char s[n+1]={0}; scanf("%s",s); int ans=0; int cu=(k>>1); for(int i=0;i<cu;++i){ int cnt[28]={0}; int qwq=0; for(int j=0;j<n/k;++j){ cnt[s[j*k+i]-'a']++; cnt[s[(j+1)*k-i-1]-'a']++; } for(int j=0;j<26;++j) qwq=max(qwq,cnt[j]); ans+=qwq; } if (k&1){ int cnt[28]={0}; for(int j=0;j<n/k;++j){ cnt[s[j*k+cu]-'a']++; } int qwq=0; for(int j=0;j<26;++j) qwq=max(qwq,cnt[j]); ans+=qwq; } ans=n-ans; write(ans,'\n'); } return 0; }
D. Walk on Matrix (CF 1332 D)
题目大意
给定一个的网格,每个网格上有一个数字,每次可以向右或向下移动一格,要求一种移动方式,使得从移动到,且到达的格子的所有数的&运算的值最大。
然而写了个假,如图。
现在要求你构造一个矩阵,给定数字,满足以下要求:
- 真正的答案与的假答案的差值恰好为。
解题思路
构造题。从简入手。
首先的矩阵肯定不行,它们的差值为。
的矩阵也不行,它们的差值为。
的矩阵
对于真正的答案,是 (abcf表示a&b&c&f)。
对于的答案,是
我们发现两者都有考虑到,那么我们让abcf尽可能小,否则两个都会取而使得差值为0。很显然我们让为就可以了。
然后,与真正的答案是少考虑了一种情况,我们假设这个情况恰好就是最大值的情况,只考虑了,那就意味着abe>ade,但最终,且,这样就能符合题目的要求了。
那我们要怎么诱导选择呢。注意到和的上限有倍的差别。由于在二进制下有16位,而有位,我们让前17位都是(),的第17位是,其他位是(),而的前位全是(),,这样,然后我们再让,因为在二进制下的第位不可能是,这样而,就可以卡掉这个假DP了。
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } int main(void) { int k; read(k); printf("2 3\n"); printf("262143 131072 0\n"); printf("131071 262143 %d\n",k); return 0; }
E. Height All the Same (CF 1332 E)
题目大意
给定一个的网格,每个格子上有若干个方块,可以进行以下两种操作:
- 对于相邻的格子(共边),可以分别放上一个方块。
- 对于一个格子,可以放上两个方块。
给定数字,求出满足以下要求的初始局面的数量:
- 每个格子初始的方块数满足。
- 通过若干次操作后可以使得所有格子的方块数相同(等高)。
解题思路
对于第二个操作,它不会改变一个格子上方块数的奇偶性。如果所有格子的奇偶性相同,那么通过若干个操作二就一定能达到等高。否则我们需要通过操作一来改变奇偶性。
如果我们要全变成偶数,而有一对相邻的格子的方块数是奇数,那么我们对这对格子进行操作一就能变成偶数。
如果一奇一偶,我们进行操作一,那么奇数数量方块的格子就会移动,如果还有一个奇数数量方块的格子,我们就可以把这个格子移动到同样是奇数数量方块的格子使它们相邻,然后再一次操作一变成偶数。
那就很显然了,如果初始局面里,只要奇数数量方块的格子数量是偶数,或者偶数数量方块的格子数量的偶数,这个局面就能得到等高的局面,而无关乎它们的位置。
那就是个简单的计数问题。在中,我们可以填个奇数,个偶数。
当是偶数,
当是奇数,
神奇的代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; template <typename T> void read(T &x) { int s = 0, c = getchar(); x = 0; while (isspace(c)) c = getchar(); if (c == 45) s = 1, c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); if (s) x = -x; } template <typename T> void write(T x, char c = ' ') { int b[40], l = 0; if (x < 0) putchar(45), x = -x; while (x > 0) b[l++] = x % 10, x /= 10; if (!l) putchar(48); while (l) putchar(b[--l] | 48); putchar(c); } const LL mo=998244353; LL qpower(LL a,LL b){ LL qwq=1; while(b){ if (b&1) qwq=qwq*a%mo; a=a*a%mo; b>>=1; } return qwq; } LL inv(LL a){ return qpower(a,mo-2); } int main(void) { LL n,m,l,r; read(n); read(m); read(l); read(r); LL a=(r+1)/2-l/2; LL b=r/2-(l-1)/2; LL ans=0; if (((n&1)==0)||((m&1)==0)) ans=(qpower(a+b,n*m)+qpower(a-b,n*m))%mo*inv(2)%mo; else ans=qpower(a+b,n*m); write(ans,'\n'); return 0; }
这次才注意到resubmission会-50白白扣了3次qwq
本文作者:~Lanly~
本文链接:https://www.cnblogs.com/Lanly/p/12611629.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步