Codeforces Codeforces Round #452 (Div. 2)(899A-899F) 题解
来源:互联网 发布:泰迪体质 知乎 编辑:程序博客网 时间:2024/06/18 11:44
总结
这是我上紫后第一次去打div2,感觉十分的休闲。鉴于我最后不够时间写F的惨痛经历,我决定下次打div2的时候要从后往前做。
达成成就:get到了人生的第一次被hack,这里截图以作留念。
由于这是div2,总体来讲并不难,有很多人1h左右就已经ak了。但由于种种原因我用了1h才搞完abc,果然还是要加强对细节题的快速处理。
A. Splitting in Teams
送分题,怎么做都行。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;const int N=200005;int n,a[N],t[3];int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int main(){ n=read(); for (int i=1;i<=n;i++) { int x=read(); t[x]++; } int ans=min(t[1],t[2]); t[1]-=ans;t[2]-=ans; ans+=t[1]/3; printf("%d",ans); return 0;}
B. Months and Years
由于n很小所以暴力枚举开始月份然后扫一遍即可。一开始被hack掉是因为我没判断数据中有两个连续闰年的情况。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;const int N=45;int n,a[N],d[12]={31,28,31,30,31,30,31,31,30,31,30,31},t[N];int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int main(){ n=read(); for (int i=1;i<=n;i++) a[i]=read(),t[a[i]]++; if (t[29]>1) {puts("NO");return 0;} for (int i=0;i<12;i++) { int flag=0; for (int now=i,j=1;j<=n;j++,now=(now+1)%12) if (now==1) { if (a[j]!=28&&a[j]!=29) {flag=1;break;} } else { if (a[j]!=d[now]) {flag=1;break;} } if (!flag) {puts("YES");return 0;} } puts("NO"); return 0;}
C. Dividing the numbers
这题的水法有很多。我的方法是从大到小贪心选数来逼近s/2,其中s表示1到n的和。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int N=60005;int n,ans[N];void solve(LL s){ int tot=0;LL w=0; for (int i=n;i>=1;i--) if (s>=i) s-=i,ans[++tot]=i,w+=i; printf("%I64d\n%d ",abs((LL)n*(n+1)/2-w*2),tot); for (int i=tot;i>=1;i--) printf("%d ",ans[i]);}int main(){ scanf("%d",&n); LL s=(LL)n*(n+1)/2; solve((s+1)/2); return 0;}
D. Shovel Sale
这题好就好在限定的数是9,要是换成其他数的话估计就会麻烦很多,至少对我的方法来说是这样的。数位dp,设f[i,j,0/1,0/1]表示有多少数对(x,y)满足(x>=y)且从高到底做到第i位,从第i位开始连续9的个数为j,x是否卡着n的上界,x是否等于y。由于这里要求的是9,不难发现从最低位到第len位都是不用进位的,其中len表示后缀9的长度,所以这里转移的时候也不用考虑进位的问题。转移完之后我还dp了一次,是为了减掉y=0的情况。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;int n,a[15],g[15][2],a1;LL f[15][15][2][2];int work(int mx){ g[a1+1][1]=1; for (int i=a1+1;i>mx+1;i--) { if (g[i][0]) g[i-1][0]+=g[i][0]*10; if (g[i][1]) { g[i-1][1]+=g[i][1]; g[i-1][0]+=g[i][1]*a[i-1]; } } int ans=0,flag=0; for (int i=1;i<=mx;i++) if (a[i]!=9) {flag=1;break;} if (!flag) return g[mx+1][0]+g[mx+1][1]; else return g[mx+1][0];}int main(){ scanf("%d",&n); int tmp=n; while (tmp) a[++a1]=tmp%10,tmp/=10; f[a1+1][0][1][1]=1; for (int i=a1+1;i>1;i--) for (int j=0;j<=a1;j++) { if (f[i][j][0][0]) { LL w=f[i][j][0][0]; for (int x=0;x<=9;x++) for (int y=0;y<=9;y++) if (x+y==9) f[i-1][j+1][0][0]+=w; else f[i-1][0][0][0]+=w; } if (f[i][j][0][1]) { LL w=f[i][j][0][1]; for (int x=0;x<=9;x++) { f[i-1][0][0][1]+=w; for (int y=0;y<x;y++) if (x+y==9) f[i-1][j+1][0][0]+=w; else f[i-1][0][0][0]+=w; } } if (f[i][j][1][0]) { LL w=f[i][j][1][0]; for (int x=0;x<=9;x++) if (x+a[i-1]==9) f[i-1][j+1][1][0]+=w; else f[i-1][0][1][0]+=w; for (int x=0;x<a[i-1];x++) for (int y=0;y<=9;y++) if (x+y==9) f[i-1][j+1][0][0]+=w; else f[i-1][0][0][0]+=w; } if (f[i][j][1][1]) { LL w=f[i][j][1][1]; f[i-1][0][1][1]+=w; for (int x=0;x<a[i-1];x++) if (x+a[i-1]==9) f[i-1][j+1][1][0]+=w; else f[i-1][0][1][0]+=w; for (int x=0;x<a[i-1];x++) { f[i-1][0][0][1]+=w; for (int y=0;y<x;y++) if (x+y==9) f[i-1][j+1][0][0]+=w; else f[i-1][0][0][0]+=w; } } } int mx=0; for (int i=a1;i>=0;i--) if (f[1][i][0][0]+f[1][i][1][0]>0) {mx=i;break;} if (!mx) {printf("%I64d",(LL)n*(n-1)/2);return 0;} printf("%I64d",f[1][mx][0][0]+f[1][mx][1][0]-(LL)work(mx)); return 0;}
E. Segments Removal
直接用线段树来维护最长连续序列同时支持删除即可。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;const int N=200005;int n,a[N];struct tree{int mx,pl,pr,s,l,r,sl,sr,ppl,ppr;}t[N*5];int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}void updata(int d,int l,int r){ int mid=(l+r)/2; if (!t[d*2].mx) t[d]=t[d*2+1]; else if (!t[d*2+1].mx) t[d]=t[d*2]; else { t[d].s=t[d*2].s+t[d*2+1].s; if (t[d*2].sl==t[d*2].s&&t[d*2].l==t[d*2+1].l) t[d].sl=t[d*2].sl+t[d*2+1].sl,t[d].l=t[d*2].l,t[d].ppl=t[d*2+1].ppl; else t[d].sl=t[d*2].sl,t[d].l=t[d*2].l,t[d].ppl=t[d*2].ppl; if (t[d*2+1].sr==t[d*2+1].s&&t[d*2+1].r==t[d*2].r) t[d].sr=t[d*2+1].sr+t[d*2].sr,t[d].r=t[d*2+1].r,t[d].ppr=t[d*2].ppr; else t[d].sr=t[d*2+1].sr,t[d].r=t[d*2+1].r,t[d].ppr=t[d*2+1].ppr; t[d].mx=t[d*2].mx;t[d].pl=t[d*2].pl;t[d].pr=t[d*2].pr; if (t[d*2].r==t[d*2+1].l&&t[d*2].sr+t[d*2+1].sl>t[d].mx) t[d].mx=t[d*2].sr+t[d*2+1].sl,t[d].pl=t[d*2].ppr,t[d].pr=t[d*2+1].ppl; if (t[d*2+1].mx>t[d].mx) t[d].mx=t[d*2+1].mx,t[d].pl=t[d*2+1].pl,t[d].pr=t[d*2+1].pr; }}void build(int d,int l,int r){ if (l==r) { t[d].sl=t[d].sr=1; t[d].l=t[d].r=a[l]; t[d].mx=1; t[d].pl=t[d].pr=t[d].ppl=t[d].ppr=l; t[d].s=1; return; } int mid=(l+r)/2; build(d*2,l,mid);build(d*2+1,mid+1,r); updata(d,l,r);}void ins(int d,int l,int r,int x,int y){ if (x>y) return; if (l==x&&r==y) { t[d].l=t[d].r=t[d].sl=t[d].sr=t[d].mx=t[d].pl=t[d].pr=t[d].s=t[d].ppl=t[d].ppr=0; return; } int mid=(l+r)/2; ins(d*2,l,mid,x,min(y,mid)); ins(d*2+1,mid+1,r,max(x,mid+1),y); updata(d,l,r);}int main(){ n=read(); for (int i=1;i<=n;i++) a[i]=read(); build(1,1,n); int ans=0; while (t[1].mx) { ins(1,1,n,t[1].pl,t[1].pr); ans++; } printf("%d",ans); return 0;}
F. Letters Removing
一开始想的是开62棵线段树,后来发现只用开一棵线段树来支持找对应区间,用62个set来找到删除的位置即可。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<set>using namespace std;const int N=200005;int n,m;char s[N];struct tree{int s;}t[N*5];set<int> w[65];bool f[N];int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int get_num(char c){ if (c>='a'&&c<='z') return c-'a'+1; if (c>='A'&&c<='Z') return c-'A'+27; return c-'0'+53;}void build(int d,int l,int r){ t[d].s=r-l+1; if (l==r) return; int mid=(l+r)/2; build(d*2,l,mid);build(d*2+1,mid+1,r);}void ins(int d,int l,int r,int x){ t[d].s--; if (l==r) return; int mid=(l+r)/2; if (x<=mid) ins(d*2,l,mid,x); else ins(d*2+1,mid+1,r,x);}int query(int d,int l,int r,int k){ if (l==r) return l; int mid=(l+r)/2; if (t[d*2].s>=k) return query(d*2,l,mid,k); else return query(d*2+1,mid+1,r,k-t[d*2].s);}int main(){ n=read();m=read(); scanf("%s",s+1); for (int i=1;i<=n;i++) { int x=get_num(s[i]); w[x].insert(i); } build(1,1,n); while (m--) { int l=read(),r=read(); char ch[2];scanf("%s",ch); int x=get_num(ch[0]); l=query(1,1,n,l);r=query(1,1,n,r); set<int>::iterator it=w[x].lower_bound(l); while (it!=w[x].end()&&(*it)<=r) { ins(1,1,n,(*it));f[(*it)]=1; w[x].erase(it),it;it=w[x].lower_bound(l); } } for (int i=1;i<=n;i++) if (!f[i]) putchar(s[i]); return 0;}
阅读全文
0 0
- Codeforces Codeforces Round #452 (Div. 2)(899A-899F) 题解
- Codeforces Round #442 (Div. 2) 题解(877A~F)
- Codeforces Round #452 (Div. 2) A-C题解
- Codeforces Round #452 (Div. 2) 12-17 A-C 题解
- 【codeforces】Codeforces Round #276 (Div. 2) 题解
- 【codeforces】Codeforces Round #277 (Div. 2) 题解
- 【codeforces】Codeforces Round #279 (Div. 2) 题解
- 【codeforces】Codeforces Round #283 (Div. 2) 【题解】
- 【codeforces】Codeforces Round #291 (Div. 2) 题解
- Codeforces Beta Round #34 (Div. 2) A题解题报告
- Codeforces Round #179 (Div. 2) A题解题报告
- Codeforces Round #188 (Div. 2) A题解题报告
- Codeforces Round #185 (Div. 2) A题解题报告
- Codeforces Round #241 (Div. 2) A B C题解
- Codeforces Round #277 (Div. 2) A~E题解
- Codeforces Round #292 (Div. 2) A,B,C,D 题解
- Codeforces Round #303 (Div. 2) A,B,D题解
- Codeforces Round #304 (Div. 2) A,B,C题解
- 小程序搜索不到?
- 12.15~12.16培训总结
- [DP]Atcoder ARC 087 D
- 记一次Base64以及URLEncode转码过程中浏览器请求后台问题
- mysql 中any, some, and的用法
- Codeforces Codeforces Round #452 (Div. 2)(899A-899F) 题解
- java多线程[5]:信号量(Semaphore)
- spring Security 投票器
- 扫描二维码
- 第三部分 Makefile 的工程组织
- 8.5
- 数据库的基本操作
- html游戏
- nginx平台初探