Codeforces Round #693 (Div. 3)题解
题目链接:Dashboard - Codeforces Round #693 (Div. 3) - Codeforces
A. Cards for Friends
题意:给定长为n,宽为m的一张纸片;纸片长或宽为偶数时可被裁剪为相同的新的两张纸片,则原纸片能否至少被裁剪为k张。
思路:剪就是了。
代码:
int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); //IO cin>>t; while(t--) { ll w,h; cin>>w>>h>>n; ll sum=1; while(w%2==0) { sum*=2; w/=2; } while(h%2==0) { sum*=2; h/=2; } if(sum>=n)yes; else no; } }
B. Fair Division
题意:给定n颗糖果,糖果权值是1或2,能否将糖果分为两部分使得两部分各总权值相等。
思路:若权值为1糖果数量为奇,则总权值为奇,一定不可平分。若权值为1糖果数量为偶,考虑权值为2糖果数量;若为偶,则全部平分,若为奇,则在平分后多出1颗,至少需要两颗权值为1糖果补足。
代码:
int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); //IO cin>>t; while(t--) { cin>>n; ll sum1=0,sum2=0; rep(i,1,n) { ll x; cin>>x; if(x==1)sum1++; else sum2++; } if(sum1%2)no; else { if(sum2%2&&sum1<2)no; else yes; } } }
ll F(ll x) { if(x>n)return 0; if(dp[x]!=-1)return dp[x]; dp[x]=F(x+a[x])+a[x]; return dp[x]; } int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); //IO cin>>t; while(t--) { mem(dp,-1); cin>>n; rep(i,1,n)cin>>a[i]; ll maxn=-1; rep(i,1,n)maxn=max(maxn,F(i)); cout<<maxn<<endl; } }
D. Even-Odd Game
题意:给定n个数,Alice和Bob轮流操作,不能不操作,Alice先手。Alice选择偶数时得分增加a[i],奇数不加分;Bob选择奇数时得分增加a[i],偶数不加分。
双方选择最优方案,询问结果。
思路:加分最优拿最大,不加分最优拿最大。
代码:
int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); //IO cin>>t; while(t--) { cin>>n; ll bob=0,alice=0; rep(i,1,n)cin>>a[i]; sort(a+1,a+1+n,greater<ll>()); rep(i,1,n) { if(i%2==1) { if(a[i]%2==0)alice+=a[i]; } else { if(a[i]%2==1)bob+=a[i]; } } if(alice>bob)cout<<"Alice"<<endl; else if(alice<bob)cout<<"Bob"<<endl; else cout<<"Tie"<<endl; } }
E. Correct Placement
思路:贪心排序,阅读理解……
代码:
struct node { ll h,w,n,ans; }a[N]; bool cmp1(node a,node b) { if(a.h==b.h)return a.w>b.w; return a.h<b.h; } bool cmp2(node a,node b) { return a.n<b.n; } int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); //IO cin>>t; while(t--) { cin>>n; rep(i,0,n-1) { cin>>a[i].h>>a[i].w; a[i].n=i; a[i].ans=-1; if(a[i].h>a[i].w)swap(a[i].h,a[i].w); } sort(a,a+n,cmp1); ll minn=0; rep(i,1,n-1) { if(a[i].w>a[minn].w)a[i].ans=a[minn].n+1; if(a[i].w<a[minn].w)minn=i; } sort(a,a+n,cmp2); rep(i,0,n-1)cout<<a[i].ans<<" "; cout<<endl; } }
F. New Year's Puzzle(补)
题意:给定一个n*2的长方形,其中m个格子已经被填充,给出mge格子的坐标,剩下的部分能否被1*2的骨牌(可旋转)填满。
思路:从左向右递推,根据情况分类模拟(其实还挺有意思的
代码:
struct node { ll x,y; }a[N]; bool cmp(node a,node b) { if(a.y==b.y)return a.x<b.x; return a.y<b.y; } int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); //IO cin>>t; while(t--) { cin>>n>>m; rep(i,1,m)cin>>a[i].x>>a[i].y; sort(a+1,a+1+m,cmp); ll up=0,down=0,flag=1; a[m+1].y=0; rep(i,1,m) { ll upp=a[i].y-up-1; ll downn=a[i].y-down-1; if(a[i].y==a[i+1].y) { if(upp==downn) { up=a[i].y; down=a[i].y; } else flag=0; i++; } else if(a[i].x==1) { if(up==down) { up=a[i].y; down=a[i].y-1; } else { if(upp%2==0) { up=a[i].y; down=a[i].y; } else flag=0; } } else { if(up==down) { up=a[i].y-1; down=a[i].y; } else { if(downn%2==0) { up=a[i].y; down=a[i].y; } else flag=0; } } } if(up!=down)flag=0; if(flag)yes; else no; } }
G. Moving to the Capital
题意:给定一张有向图,定义点权为距离点1的最短距离,定义两种操作,第一种为从点i到沿路径到点j且d[i]<d[j],第二种为d[i]>=d[j];其中第二种操作至多使用1次,询问每个点到点1所需的最小操作次数。
思路:先跑一次dijkstra求权值,然后标记两种线段跑dfs(记忆化搜索)
代码:
vector<ll>vec[N],c[N]; void dijkstra(ll tt) { queue<ll>q; dis[tt]=0; vis[tt]=1; q.push(tt); while(!q.empty()) {N ll u=q.front(); q.pop(); c[dis[u]].push_back(u); ll len=vec[u].size(); rep(i,0,len-1) { ll v=vec[u][i]; if(vis[v])continue; dis[v]=dis[u]+1; vis[v]=1; q.push(v); } } } /*ll dfs(ll k,ll flag) { if (dp[k][flag]!=1e6) return dp[k][flag]; else {dp[k][flag]=dis[k]; for(auto v:vec[k]) { if(dis[v]>dis[k]) { dp[k][flag]=min(dp[k][flag],dfs(v,flag)); } else { if(!flag)dp[k][flag]=min(dp[k][flag],dfs(v,1)); } } return dp[k][flag];} }*/ int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); //IO cin>>t; while(t--) { mem(vis,0); rep(i,1,n) { vec[i].clear(); c[i].clear(); } cin>>n>>m; rep(i,1,m) { cin>>u>>v; vec[u].push_back(v); } dijkstra(1); rep(i,1,n)f[i]=dis[i]; per(l,n-1,1) { ll num=c[l].size(); rep(i,0,num-1) { ll u=c[l][i],len=vec[u].size(); rep(j,0,len-1) { ll v=vec[u][j]; if(dis[u]<dis[v])f[u]=min(f[u],f[v]); else f[u]=min(f[u],dis[v]); } } } rep(i,1,n)cout<<f[i]<<" "; cout<<endl; } }

浙公网安备 33010602011771号