Codeforces Round 857 (Div. 2)
A. Likes
求每回合最大的数列:先全使用正数,每个正数对ans++,再全使用负数,每个负数对ans--
求每回合最小的数列:方法1(模拟):若有负数未被使用且目前点赞数>0,则使用负数对ans--;否则使用正数
方法2(绝对值排序):按照绝对值从小到大排序,依次按正数,负数相应对ans操作
void solve(){ int n=read(); int l=0,d=0; for(int i=1;i<=n;i++){ int x=read(); if(x>0) l++; else d++; } int l1=l,dd=d,ans=0; while(l1--){ ans++; cout<<ans<<" "; }while(dd--){ ans--; cout<<ans<<" "; } cout<<endl; ans=0; while(l||d){ if(ans&&d){ d--; ans--; }else { l--; ans++; } cout<<ans<<" "; } cout<<endl; }
B. Settlement of Guinea Pigs
按照题意有推论:(1) 未确认性别的小豚鼠只能一个人一个房子 记为L
(2) 已确认性别的小豚鼠若有n只,则这n只需(n+2)/2个房子 记为D
所以我们可以模拟过程,记录过程中的 ans=max(D+L,ans)
void solve(){ int n=read(); int l=0,d=0,need=0,ans=0; for(int i=1;i<=n;i++){ int x=read(); if(x==1) l++; else { if(d==0)need=max(need,l); else need=max(need,(d+2)/2+l); d+=l; l=0; } if(need>ans){ ans=need; } } if(l){ if(d==0)need=max(need,l); else need=max(need,(d+2)/2+l); d+=l; l=0; if(need>ans){ ans=need; } } cout<<ans<<endl; }
C. The Very Beautiful Blanket
根据题目样例,需要构造每四个数的矩阵异或和为0,且矩阵内每个数不同
void solve(){ int n=read(),m=read(); cout<<n*m<<endl; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<(i<<10)+j<<" \n"[j == m - 1]; } } }
D. Buying gifts
贪心题 依然学习jiangly的代码 (一开始没看明白,后面把mx的数输出又看了半天 发现妙啊)
先把所有店的两种物品都放在一起排序,同时记录val和给谁的,然后用bad记录目前未经历的店家数量
若bad为0 说明所有店家都经历过了,因为经过排序,目前每个人手上都是必须拥有的最小价值,同时利用mx迭代最大和第二大的val,再利用2*2的格子对可能的格子进行比较,注意排除同一个店里的情况
void solve(){ int n=read(); vector<PII>a(2*n); for(int i=0;i<n;i++){ int x=read(),y=read(); a[2*i]={x,2*i}; a[2*i+1]={y,2*i+1}; } sort(a.begin(),a.end()); PII mx[2][2]; for(int i=0;i<2;i++){ for(int j=0;j<2;j++){ mx[i][j]={-1,-1}; } } vector<bool>vis(n); int bad=n,ans=1e9; for(auto [v,t]:a){ int u=t%2; mx[u][1]=mx[u][0]; mx[u][0]={v,t}; bad-=!vis[t/2]; vis[t/2]=true; for(int i=0;i<2;i++){ if(bad==0&&mx[!u][i].second!=-1&&mx[!u][i].second!=(t^1)){ ans=min(ans,v-mx[!u][i].first); } } } cout<<ans<<endl; }