Codeforces Round #401 (Div. 2)
本来可以AK的一场比赛。
结果因为自己十分脑残,代码各种出错。
事实证明:不能在学校的晚饭时间不吃饭打CF
A. Shell Game
SBT,发现6是一个循环节,膜掉就可以模拟了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) int n,k; int a[3]={0,1,2}; int main() { scanf("%d%d",&n,&k); n%=6; F(i,1,n) { if (i&1) swap(a[0],a[1]); else swap(a[1],a[2]); } printf("%d\n",a[k]); }
B. Game of Credit Cards
贪心即可,手残-1
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) int n; char s1[2005],s2[2005]; int a[2005],b[2005]; int cnt1[11],cnt2[11],ans1,ans2; int main() { scanf("%d",&n); scanf("%s",s1+1); scanf("%s",s2+1); F(i,1,n) a[i]=s1[i]-'0',b[i]=s2[i]-'0',cnt1[b[i]]++,cnt2[b[i]]++; F(i,1,n) { int flag=0; F(j,a[i]+1,9) { if (cnt1[j]) { cnt1[j]--; ans1++; flag=1; break; } } if (flag) continue; else { F(j,0,a[i]) { if (cnt1[j]) { cnt1[j]--; break; } } } } F(i,1,n) { int flag=0; F(j,a[i],9) { if (cnt2[j]) { cnt2[j]--; flag=1; break; } } if (flag) continue; else { ans2++; F(j,0,a[i]-1) { if (cnt2[j]) { cnt2[j]--; break; } } } } cout<<ans2<<endl<<ans1<<endl; }
C. Alyona and Spreadsheet
这题目,遇到N*M<=S的这种条件,简直爆炸。必须要交换nm,分类讨论。简直是二合一题目。
我的做法是如果n大,算一列,扫一遍询问。
如果m打,每次往后算一位,扫一遍询问
垃圾题目,在总共2h的情况下调了1h
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) #define inf 0x3f3f3f3f int a[100005][405]; int ans[100005],l[100005],r[100005]; int n,m,k,dp[100005]; int main() { scanf("%d%d",&n,&m); if (n>=m) { F(i,1,n) F(j,1,m) scanf("%d",&a[i][j]); scanf("%d",&k); F(i,1,k) scanf("%d%d",&l[i],&r[i]); F(j,1,m) { F(i,1,n) { if (a[i][j]>=a[i-1][j]) dp[i]=dp[i-1]; else dp[i]=i; } F(i,1,k) if (dp[r[i]]<=l[i]) ans[i]|=1; } F(i,1,k) if (ans[i]) printf("Yes\n"); else printf("No\n"); } else { F(i,1,n) F(j,1,m) scanf("%d",&a[j][i]); scanf("%d",&k); F(i,1,k) scanf("%d%d",&l[i],&r[i]); F(j,1,n) { int now=inf; F(i,1,m) { if (a[i][j]<a[i][j-1]) { dp[i]=j; } now=min(now,dp[i]); } F(i,1,k) { if (r[i]==j&&now<=l[i]) ans[i]|=1; } } F(i,1,k) if (ans[i]) printf("Yes\n"); else printf("No\n"); } }
D. Cloud of Hashtags
全是细节题目,让我可怎么办
直接扫一遍,比较的时候注意一下,手残把int开成了char,-3还过不了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) char a[5000005],s[1000005]; int l[1000005],r[1000005],now=1; int n; int main() { scanf("%d",&n); F(i,1,n) { // printf("now is %d\n",i); scanf("%s",s); int len=strlen(s+1); l[i]=now; F(j,1,len)a[now+j-1]=s[j]; r[i]=now+len-1; now=r[i]+1; } D(i,n-1,1) { int l1=r[i]-l[i]+1,l2=r[i+1]-l[i+1]+1; if (l1<l2) { int pos=r[i]; F(j,1,l1) if (a[j+l[i]-1]>a[j+l[i+1]-1]){pos=j+l[i]-2;break;} else if (a[j+l[i]-1]<a[j+l[i+1]-1]) break; r[i]=pos; } else if (l1==l2) { int pos=r[i]; F(j,1,l1) if (a[j+l[i]-1]>a[j+l[i+1]-1]){pos=j+l[i]-2;break;} else if (a[j+l[i]-1]<a[j+l[i+1]-1]) break; r[i]=pos; } else { int pos=r[i]; F(j,1,l2) if (a[j+l[i]-1]>a[j+l[i+1]-1]){pos=j+l[i]-2;break;} else if (a[j+l[i]-1]<a[j+l[i+1]-1]) break; else if (j==l2) pos=j+l[i]-1; if (!l2) pos=l[i]-1; r[i]=pos; } } F(i,1,n) { printf("#"); F(j,l[i],r[i]) printf("%c",a[j]); printf("\n"); } }
E. Hanoi Factory
看到题目我慌了。D还没过。
看了看貌似可以按照b排序。
然后发现对于当前的i,我们可以找到后面能落在上面的进行转移
dp[i]=dp[j]+hi,当j可以落在i上,即ai<bj<bi,发现如此做就比较容易了,因为j的约束只剩下bj了。
然后可以用线段树优化,二分可行的范围然后在线段树上查询即可。
手残写挂二分,样例太弱,一直WA on 4
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (ll i=j;i<=k;++i) #define D(i,j,k) for (ll i=j;i>=k;--i) #define ll long long struct node{ll a,b,h;}c[100005]; ll n; struct Segment_Tree { ll mx[(100005)*8],X,C,L,R; void modify(ll o,ll l,ll r) { if (l==r) {mx[o]=C; return ;} ll mid=l+r>>1; if (X<=mid) modify(o<<1,l,mid); else modify(o<<1|1,mid+1,r); mx[o]=max(mx[o<<1],mx[o<<1|1]); } ll qmax(ll o,ll l,ll r) { if (L<=l&&r<=R) return mx[o]; ll mid=l+r>>1; if (L>mid) return qmax(o<<1|1,mid+1,r); if (R<=mid) return qmax(o<<1,l,mid); else return max(qmax(o<<1|1,mid+1,r),qmax(o<<1,l,mid)); } }Tree; bool cmp(node x,node y) {return x.b==y.b?x.a>y.a:x.b>y.b;} int main() { scanf("%I64d",&n); F(i,1,n) scanf("%I64d%I64d%I64d",&c[i].a,&c[i].b,&c[i].h); sort(c+1,c+n+1,cmp); Tree.X=n;Tree.C=c[n].h;Tree.modify(1,1,n); D(i,n-1,1) { ll l,r,lans=0,rans=n; l=i+1;r=n; while (l<r) { ll mid=(l+r>>1)+1; if (c[i].a<c[mid].b) l=mid; else r=mid-1; } if (c[l].b<=c[i].a) l--; lans=i+1;rans=l; if (rans<lans) { Tree.X=i;Tree.C=c[i].h; Tree.modify(1,1,n); continue; } Tree.L=lans;Tree.R=rans; Tree.X=i;Tree.C=Tree.qmax(1,1,n)+c[i].h; Tree.modify(1,1,n); } Tree.L=1;Tree.R=n; printf("%I64d\n",Tree.qmax(1,1,n)); }
气死我了,看来我不适合打CF