前言:
期末考试重修还更博客= - =)
A. Cards for Friends
直接按题意模拟,看可以分成多少个2的次幂.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+500; int w[N]; int main() { int T; scanf("%d",&T); while(T--) { int n; int x,y; cin>>x>>y>>n; int res=1; while(x%2==0) { res*=2; x/=2; } while(y%2==0) { res*=2; y/=2; } if(res>=n) puts("YES"); else puts("NO"); } return 0; }
B. Fair Division
方法1:直接模拟,因为糖果一定是2/1的,就两种情况,所以你先把2的分析完奇偶讨论下即可.
#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { int T; scanf("%d",&T); while(T--) { int n; int cnt[3];memset(cnt,0,sizeof cnt); scanf("%d",&n);int x; for(int i=1;i<=n;i++) scanf("%d",&x),cnt[x]++; if(cnt[2]&1) { cnt[1]-=2; if(cnt[1]<0) puts("NO"); else if(cnt[1]&1) puts("NO"); else puts("YES"); } else { if(cnt[1]&1) puts("NO"); else puts("YES"); } } return 0; }
方法2:假如不止1,2两种糖果咋办,题目要你平分,所以假如一个数在%sum/2之前出现过,就必然会有种平分方案.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+500; ll w[N]; map<ll,bool>mp; int main() { int T; //T=1; scanf("%d",&T); while(T--) { mp.clear(); int n; ll sum=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lld",&w[i]); sum+=w[i]; }int flag=0; if(sum%2!=0) { puts("NO");flag=1; }sum/=2;ll res=0; for(int i=1;i<=n;i++) { if(sum==0) break; res+=w[i]; res%=sum; if(mp[res]&&!flag) { puts("YES"); flag=1;break; }mp[res]=true; } if(!flag) puts("NO"); } return 0; }
C. Long Jumps
题目已知这个方程,直接写个for就好了.
#include <bits/stdc++.h> using namespace std; const int N=2e5+500; typedef long long ll; ll f[N];int a[N]; int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),f[i]=a[i]; ll ans=0; for(int i=1;i<=n;i++) { ans=max(f[i],ans); if(i+a[i]>n) continue; f[i+a[i]]=max(f[i+a[i]],f[i]+a[i+a[i]]); }cout<<ans<<'\n'; } return 0; }
D. Even-Odd Game
把奇偶分开,然后我们站在Alice和BOb的角度进行选择,假如你是Alice,Bob选下一个获得比你多,那么你肯定是不让Bob加分,Alice同理.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+500; int even[N],odd[N]; bool cmp(int A,int B) { return A>B; } int main() { int T; scanf("%d",&T); while(T--) { ll res_A=0,res_B=0; int idA=0,idB=0; int n;scanf("%d",&n); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); if(x&1) odd[++idB]=x; else even[++idA]=x; } sort(even+1,even+1+idA,cmp); sort(odd+1,odd+1+idB,cmp); int nA=1,nB=1; for(int i=1;i<=n;i++) { if(i&1)//Alice选择 { if(nB<=idB&&nA<=idA) { if(even[nA]>odd[nB]) res_A+=even[nA],nA++; else nB++; } else if(nB<=idB) nB++; else res_A+=even[nA],nA++; } else//Bob选择. { if(nB<=idB&&nA<=idA) { if(even[nA]<odd[nB]) res_B+=odd[nB],nB++; else nA++; } else if(nA<=idA) nA++; else res_B+=odd[nB],nB++; } } if(res_A>res_B) puts("Alice"); else if(res_A==res_B) puts("Tie"); else puts("Bob"); } return 0; }
E. Correct Placement
无法就是让你在二维平面找到两维都比自己小的数,另一种方案就是x,y交换一下放入数组,然后我们维护一维,另外一维维护一个min即可.
#include <bits/stdc++.h> using namespace std; const int N=2e5+500; int ans[N<<1]; struct Tree{ int l,r,idx; }w[N<<1]; bool cmp(Tree A,Tree B) { if(A.l==B.l) return A.r<B.r; else return A.l<B.l; } int _val[N<<1],_id[N<<1];//维护到了i,r的最小值以及下标即可. int main() { int T;scanf("%d",&T); while(T--) { int n;scanf("%d",&n); int id=n; for(int i=1;i<=n;i++) { ans[i]=0; scanf("%d%d",&w[i].l,&w[i].r);w[i].idx=i; w[++id].l=w[i].r;w[id].r=w[i].l,w[id].idx=i; }sort(w+1,w+1+id,cmp); int last=-1;//维护前一个r的最小值即可. _val[0]=2e9,_id[0]=-1; for(int i=1;i<=id;i++) { _val[i]=_val[i-1],_id[i]=_id[i-1]; if(w[i].r<_val[i]) _val[i]=w[i].r,_id[i]=w[i].idx; if(w[i].l>w[i-1].l) { last=i-1; if(w[i].r>_val[i]) ans[w[i].idx]=_id[i]; else ans[w[i].idx]=-1; } else//只能找last前面的数. { if(w[i].r>_val[last]) ans[w[i].idx]=_id[last]; else ans[w[i].idx]=-1; } } for(int i=1;i<=n;i++) printf("%d ",ans[i]); puts(""); } }
F. New Year's Puzzle
简单模拟即可.模拟每个障碍下你是不是能填完,然后假如可以填完就是YES,否则就是NO.
#include <bits/stdc++.h> using namespace std; const int N=2e5+500; struct Graph { int r,c; }w[N]; bool cmp(Graph A,Graph B) { if(A.c==B.c) return A.r<B.r; else return A.c<B.c; } int main() { int T;scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d",&w[i].r,&w[i].c); int r1=0,r2=0;//设置我已经填到哪里了. bool flag=true;sort(w+1,w+1+m,cmp); w[++m].r=1,w[m].c=n+1; w[++m].r=2,w[m].c=n+1; for(int i=1;i<=m;i++) { //cout<<r1<<' '<<r2<<endl; if(w[i].c==w[i+1].c)//两个一起处理. { //cout<<r1<<' '<<w[i].c<<endl; if((max(r2,r1)-min(r2,r1))&1) flag=false; r1=r2=w[i].c; i++; } else//单个处理 { int p=w[i].r;//在第p行. if(p==1) { if((w[i].c-r1)%2!=1&&((max(r2,r1)-min(r2,r1))%2!=0)) flag=false; if((w[i].c-r1)%2==1) r1=w[i].c; else if((w[i].c-r1)%2!=1&&((max(r2,r1)-min(r2,r1))%2==0)) r1=w[i].c,r2=w[i].c-1; } else { if((w[i].c-r2)%2!=1&&((max(r2,r1)-min(r2,r1))%2!=0)) flag=false; if((w[i].c-r2)%2==1) { r2=w[i].c; } else if(((w[i].c-r2)%2!=1)&&((max(r2,r1)-min(r2,r1))%2==0)) { r2=w[i].c,r1=w[i].c-1; } } } }//cout<<flag<<endl; if(flag) puts("YES"); else puts("NO"); } return 0; } /* 1 6 3 2 1 1 3 2 5 NO 1 5 2 2 2 2 3 YES */
G. Moving to the Capital
dp,先跑出题意要求的d[]数组,然后我们获得了一个bfs序,然后我们更新一次f[i],最后按bfs序更新一次即可.
#include <bits/stdc++.h> using namespace std; const int N=2e5+50; int f[N],d[N]; vector<int>v[N]; vector<int>q; int main() { int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) v[i].clear(),d[i]=-1; d[1]=0;q.clear(); for(int i=1;i<=m;i++) { int x,y;scanf("%d%d",&x,&y); v[x].push_back(y); }q.push_back(1); for(int i=0;i<n;i++) { int u=q[i]; for(int x:v[u]) { if(d[x]==-1) { d[x]=d[u]+1; q.push_back(x); } } }//跑出所有d[i]. for(int i=1;i<=n;i++) { f[i]=d[i]; for(int x:v[i]) { f[i]=min(f[i],d[x]); } }//预处理出来每个f[i]. for(int i=n-1;i>=0;i--) { int u=q[i]; for(int x:v[u]) { if(d[u]<d[x])f[u]=min(f[u],f[x]); } }//按时间来dp. for(int i=1;i<=n;i++) printf("%d ",f[i]); puts(""); } return 0; }