目录
显示
C题调了很久竟然FST了,心碎…
题目链接
http://codeforces.com/contest/1072
A. Golden Plate
大意
给出一个盘子,我们现在需要在盘子上镶金,第一层是在盘子边缘,接下来每一层离上一层相隔 \(2\) 个格子。
我们要镶嵌 \(k\) 层,求我们需要镶嵌多少格黄金。
题解
按题意计算即可。
#include <cstdio> #include <algorithm> using namespace std; int main() { int w,h,k,ans=0; scanf("%d%d%d",&w,&h,&k); for(int i=1;i<=k;i++) { ans+=(w+h)*2-4; w-=4,h-=4; } printf("%d\n",ans); return 0; }
B. Curiosity Has No Limits
大意
给出两个序列 \(A,B (0 \leq a_i,b_i \leq 3)\),构造一个序列 \(T\),要求 \( t_i \& t_{i+1} = a_i \) 且 \( t_i | t_{i+1} = b_i \)。
题解
我们只需枚举 \(t_1\) 的值就可以利用规律:\(a \& b + a | b = a+b\) 来推算序列其余项的值。如果发现出现矛盾,说明枚举的 \(t_1\) 的值是非法的。
#include <stdio.h> int a[100005],b[100005],t[100005]; int main() { int n; scanf("%d",&n); for(int i=1;i<n;i++) scanf("%d",&a[i]); for(int i=1;i<n;i++) scanf("%d",&b[i]); for(int i=0;i<=3;i++) { bool flag=true; t[0]=i; for(int j=1;j<n;j++) { t[j]=a[j]+b[j]-t[j-1]; if((t[j-1]|t[j])!=a[j]||(t[j-1]&t[j])!=b[j]) { flag=false; break; } } if(flag) { puts("YES"); for(int i=0;i<n;i++) printf("%d ",t[i]); return 0; } } puts("NO"); return 0; }
C. Cram Time
大意
为了备考,你需要抽出两天时间看笔记,两天能够看笔记的时间分别为 \(a\) 小时和 \(b\) 小时。看完笔记 \(k\) 需要 \(k\) 小时,同一份笔记不能看两次。
现在你需要求出一种方案,使得你两天一共看的笔记尽可能多。
题解
显然,最优的方案是看 \(1 \ldots k\) 这几份笔记。(其中 \(k\) 的值应该是满足 \(k(k-1)/2 \leq a+b\) 的最大整数解)
接下来就是分配时间了,我们的原则是:让第一天的时间利用最多。
我们先计算出 \(k\),然后将耗时最多的几份笔记放入第一天的复习计划,并使得第一天的耗时恰好为 \(a\)。
把剩下的笔记放入第二天的复习计划即可。
#include <cstdio> #include <algorithm> using namespace std; int maxt,vis[80005],ans,tot; int main() { int a,b; scanf("%d%d",&a,&b); if(a==0&&b==0) { printf("0\n\n0\n\n");//其实这里是否输出空行并不会产生太大影响 return 0; } for(int i=1;;i++) { tot+=i; if(tot>a+b) { maxt=i-1; break; } } tot=0; for(int i=maxt;i>=1;i--) { if(i+tot>=a) { if(a==0) { printf("0\n"); ans=maxt; break; } printf("%d\n",min(a-tot,maxt)?maxt-i+1:maxt-i); for(int j=i+1;j<=maxt;j++) printf("%d ",j),vis[j]=1; if(min(a-tot,maxt))printf("%d\n",min(a-tot,maxt)); else puts(""); vis[min(a-tot,maxt)]=1; ans=min(a-tot,maxt)?i-1:i; break; } tot+=i; if(i==1) { printf("%d\n",maxt); for(int i=1;i<=maxt;i++) printf("%d ",i); puts(""); } } printf("%d\n",ans); if(ans==0)return 0; for(int i=1;i<=maxt;i++) if(!vis[i])printf("%d ",i); return 0; }