Codeforces Round #379 (Div. 2) 解题报告
本次CF是在今天早上深夜进行,上午有课就没有直接参加。今天早上上课坐到后排参加了virtual participation。这次CF前面的题目都非常的水,不到10分钟就轻松过了前两题,比较郁闷的是之后一直卡在C,开始是脑残的没有用二分TLE,后来又是因为一个常数打错而一直WA……于是模拟赛就只过了2道题(太弱了orz)。时间到了后很快发现了脑残错误,终于A了C题。下午上完课回到宿舍看D题才发现D题水的不行,很快就A了。不过E和F就比较超出我现在知识范围了,暂时就先放下。第一次参加virtual participation,感觉这个模式真的是很赞,以后有时间一定要多多的参加训练自己。道阻且长,加油吧!
A题
这……就数一下A和D的个数,判断一下输出就可以了。没什么可说的。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 char a[100005]; 5 int n,m=0,k=0,i; 6 int main() 7 { 8 scanf("%d",&n); 9 scanf("%s",a); 10 for(i=0;i<n;i++) 11 { 12 if(a[i]=='A') 13 m++; 14 else 15 k++; 16 } 17 if(m==k) 18 printf("Friendship\n"); 19 else if(m>k) 20 printf("Anton\n"); 21 else 22 printf("Danik\n"); 23 return 0; 24 }
B题
先尽可能组256,2、5、6个数的最小值即为可组成的256个数。2减去256个数后再取2、3个数最小值即为32个数最大值。这样相加即得到了最多的个数。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 unsigned long long int a2,a3,a5,a6,he,de; 5 unsigned long long min3(unsigned long long int x,unsigned long long int y,unsigned long long int z) 6 { 7 if(x<y) 8 return min(x,z); 9 else 10 return min(y,z); 11 } 12 int main() 13 { 14 cin>>a2>>a3>>a5>>a6; 15 de=min3(a2,a5,a6); 16 a2-=de;a5-=de; 17 a6-=de; 18 he+=de*256; 19 he+=min(a2,a3)*32; 20 cout<<he; 21 }
C题
(TLE、WA了很久,捂脸つ﹏⊂……)对于第一种魔法就是for循环,逐个判断,其中循环的内部二分查找此时第二种魔法可行中最好的一个。找到对于每一个第一种魔法的第二种魔法最优选法。注意还要看只选第二种魔法的情况。全都比较一下就找到了耗时最短的办法。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 unsigned long long int n,m,k,a[200002],b[200002],c[200002],d[200002],x,s,i,j,l,r,mid,an; 5 int main() 6 { 7 cin>>n>>m>>k; 8 cin>>x>>s; 9 for(i=1;i<=m;i++) 10 cin>>a[i]; 11 for(i=1;i<=m;i++) 12 cin>>b[i]; 13 for(i=1;i<=k;i++) 14 cin>>c[i]; 15 for(i=1;i<=k;i++) 16 cin>>d[i]; 17 b[0]=c[0]=d[0]=0; 18 a[0]=x; 19 an=x*n; 20 for(i=0;i<=m;i++) 21 { 22 if(a[i]>x||b[i]>s) 23 continue; 24 l=1;r=k; 25 j=0; 26 while(l<=r) 27 { 28 mid=(l+r)>>1; 29 if(d[mid]+b[i]>s) 30 r=mid-1; 31 else 32 { 33 l=mid+1; 34 j=max(mid,j); 35 } 36 } 37 an=min(an,(n-c[j])*a[i]); 38 } 39 cout<<an; 40 return 0; 41 }
D题
用a数组记录8个方向是否可行,b数组记录此时各个方向离目标点最近的点的距离。全都进行过判断后,再遍历一遍a数组看是否有方向满足即可。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; long long int a[10],b[10],si,sj,ti,tj,n,st,kind,di; int dir[3][10]={{1,1,1,1,1,1,1,1},{0,1,0,1,0,1,0,1},{1,0,1,0,1,0,1,0}},i; char c[10]; int val(long int x,long long int y) { long long int d1,d2; d1=x-si; d2=y-sj; if(d2==0&&d1<0) return 0; else if(d1+d2==0&&d2>0) return 1; else if(d1==0&&d2>0) return 2; else if(d1>0&&d1==d2) return 3; else if(d1>0&&d2==0) return 4; else if(d1>0&&d1+d2==0) return 5; else if(d1==0&&d2<0) return 6; else if(d1<0&&d2==d1) return 7; else return -1; } int main() { memset(b,-1,sizeof(b)); memset(a,0,sizeof(a)); scanf("%I64d",&n); scanf("%I64d%I64d",&si,&sj); while(n--) { scanf("%s%I64d%I64d",c,&ti,&tj); if(c[0]=='Q') kind=0; else if(c[0]=='B') kind=1; else kind=2; st=val(ti,tj); if(st>-1) { di=max(abs(ti-si),abs(tj-sj)); if(!dir[kind][st]) { if(di<b[st]||b[st]<0) {b[st]=di; a[st]=0; } continue; } else{ if(di<b[st]||b[st]==-1) { a[st]=1; b[st]=di; } } } else { continue; } } for(i=0;i<8;i++) { if(a[i]==1) break; } if(i<8) printf("YES\n"); else printf("NO\n"); }