Codeforces Round #767 (Div. 1)
2022/1/25 6:04:23
本文主要是介绍Codeforces Round #767 (Div. 1),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
A
https://codeforces.com/contest/1628/problem/A
可知前缀mex是单调递增的,字典序最大,则每次选择的mex都是最大的。
贪心地考虑,每次消去一个前缀,要求这个前缀的mex=全局的mex,且是最短的一个,这样可以使得剩余部分的mex也会尽可能大。
代码:
#include<bits/stdc++.h> using namespace std; const int N=2e5+10; int a[N],b[N],c[N],aa[N]; int main() { //freopen("test.in","r",stdin); int t; scanf("%d",&t); while (t) { t--; int n,mex=0; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); b[a[i]]++; while (b[mex]) mex++; } int p=1,i=1; aa[p]=mex; while (i<=n) { int la=i,me=0; while (i<=n) { c[a[i]]++; while (c[me]) me++; i++; if (me==mex) break; } for (int j=la;j<i;j++) { c[a[j]]--; b[a[j]]--; if (b[a[j]]==0) mex=min(mex,a[j]); } p++; aa[p]=mex; } printf("%d\n",p-1); for (int i=1;i<p-1;i++) printf("%d ",aa[i]); printf("%d\n",aa[p-1]); for (int i=0;i<=n;i++) b[i]=0; } }
B
https://codeforces.com/contest/1628/problem/B
手玩的时候发现,一些很长的组合回文,也会包含一些子序列,同样可以组成回文。
考虑可以组成回文的最简短子序列,也就是要求这个子序列不再包含任何可以回文的子序列。
首先是长度为1的,显然直接回文。
然后是长度为2的,形如AA
长度为3的,可以是AAA,也可以是ABA。当然,有人肯定会说A+BA,或者AB+A,这种情况其实包含了长度为1的情况,不满足最简短的定义。
长度为4的,只有AB+BA,其他的均不是最简短的。
长度为5的,只有ABC+BA,或者AB+CBA。
长度为6的,只有ABC+CBA
更长的长度没有最简短的子序列。
理性证明一下,假设有一个长度为n的最简短子序列,只考虑这个最简短子序列的首和尾的两个小字符串,显然:
1.它们各自不能是即成的回文串,比如A,AA,AAA,ABA
2.它们长度不能相同,否则这两个小串就可以组成更简短的回文子序列。
3.情况只剩下长度分别为2和3的情况,则只能是ABC+BA或AB+CBA,也不合法
综上,没有合法情况。
所以,所有的回文子序列都可以缩小成长度不超过6的最简短回文子序列。
依次判断即可。
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int g[10],a[N],b[N][4],q[4][N],fv[N],gv[N],f1[N]; int main() { //freopen("test.in","r",stdin); int t; scanf("%d",&t); while (t) { g[1]=g[2]=g[3]=0; t--; int n; scanf("%d",&n); for (int i=1;i<=n;i++) { char s[5]; scanf("%s",s+1); int p=strlen(s+1); a[i]=p; for (int j=1;j<=p;j++) b[i][j]=s[j]-'a'; g[p]++; q[p][g[p]]=i; } if (g[1]) { printf("YES\n"); continue; } int fl=0; for (int i=0;i<=30*30;i++) fv[i]=0,f1[i]=0; for (int i=1;i<=n;i++) { if (a[i]==2) { if (b[i][1]==b[i][2]) fl=1; fv[b[i][1]*26+b[i][2]]=1; //gv[b[i][1]+b[i][2]*26]=1; if (fv[b[i][1]+b[i][2]*26]||f1[b[i][1]+b[i][2]*26]) fl=1; }else { if (b[i][1]==b[i][3]) fl=1; f1[b[i][1]*26+b[i][2]]=1; gv[b[i][3]+b[i][2]*26+b[i][1]*26*26]=1; if (fv[b[i][2]+b[i][3]*26]||gv[b[i][1]+b[i][2]*26+b[i][3]*26*26]) fl=1; } } for (int i=1;i<=n;i++) if (a[i]==3) gv[b[i][3]+b[i][2]*26+b[i][1]*26*26]=0; if (fl) { printf("YES\n"); continue; } printf("NO\n"); } }
C
https://codeforces.com/contest/1628/problem/C
赛场上没想出来。
4个这样的东西就可以了。
D1
https://codeforces.com/contest/1628/problem/D1
设f[i][j]表示i次加和j次减所能到达的最大值。
假设我们已经知道了f[i-1][j]和f[i][j-1],考虑如何确定f[i][j]
假设这一轮,给出的数字是p,则f[i][j]=max(f[i-1][j]+p,f[i][j-1]+p),由于双方都绝顶聪明,
这篇关于Codeforces Round #767 (Div. 1)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享