Codeforces Round #573 (Div. 2)
A:Tokitsukaze and Enhancement
当时看错条件了。。以为A>C>B>D。就胡写了判断条件。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 bool work(int a,int b) { 5 if(a==-1) return false; 6 if(b==-1) return true; 7 if(a==1&&(b==3||b==2||b==0)) return true; 8 if(a==3&&(b==2||b==0)) return true; 9 if(a==2&&b==0) return true; 10 return false; 11 } 12 map<int,char> mp; 13 int main() { 14 mp[1]='A'; 15 mp[2]='C'; 16 mp[3]='B'; 17 mp[0]='D'; 18 int x; 19 scanf("%d",&x); 20 int ans=-1,pos=-1; 21 char strans; 22 for(int i=0;i<=2;i++) { 23 int tmp=(x+i)%4; 24 if(work(tmp,ans)) { 25 ans=tmp; 26 pos=i; 27 strans=mp[tmp]; 28 } 29 } 30 printf("%d %c",pos,strans); 31 }
看了题解,感觉还是思考太少。
根据余数,取最好的即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+10; 5 6 int main() { 7 int x; 8 scanf("%d",&x); 9 x%=4; 10 if(x==1) printf("%d %c\n",0,'A'); 11 else if(x==2) printf("%d %c\n",1,'B'); 12 else if(x==3) printf("%d %c\n",2,'A'); 13 else printf("%d %c\n",1,'A'); 14 }
B:Tokitsukaze and Mahjong
数字对应放到s,m,p组里,然后暴力找胜利的最少添加数。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 string s1,s2,s3; 5 6 vector<int> t[10]; 7 int id(char c) { 8 if(c=='s') return 1; 9 if(c=='m') return 2; 10 if(c=='p') return 3; 11 } 12 13 int a[20]; 14 15 int main() { 16 cin>>s1>>s2>>s3; 17 int id1,id2,id3; 18 id1=id(s1[1]); 19 id2=id(s2[1]); 20 id3=id(s3[1]); 21 t[id1].push_back(s1[0]-'0'); 22 t[id2].push_back(s2[0]-'0'); 23 t[id3].push_back(s3[0]-'0'); 24 int ans=4; 25 // for(int i=0;i<t[1].size();i++) printf("%d ",t[1][i]); 26 for(int i=1;i<=3;i++) { 27 memset(a,0,sizeof(a)); 28 for(int j=0;j<t[i].size();j++) { 29 a[t[i][j]]++; 30 } 31 for(int j=1;j<=9;j++) { 32 //printf("%d\n",a[j]); 33 ans=min(ans,3-a[j]); 34 } 35 int cnt; 36 for(int j=1;j<=9;j++) { 37 cnt=0; 38 for(int k=j;k<=j+2&&k<=9;k++) { 39 if(a[k]>0) cnt++; 40 } 41 //printf("%d**\n",cnt); 42 ans=min(ans,3-cnt); 43 } 44 } 45 printf("%d\n",ans); 46 47 }
C:Tokitsukaze and Discard Items
删除的数字是递增的,处理出当前要删除数字所在块的最后一个数字,然后删除,直到全部删除。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+10; 5 6 ll n,m,k,a[maxn]; 7 int main() { 8 scanf("%lld%lld%lld",&n,&m,&k); 9 for(int i=1;i<=m;i++) scanf("%lld",&a[i]); 10 int sum=0; //删除总数 11 int ans=0; 12 int now=1; 13 while(now<=m) { 14 // 没想到 15 ll r=((a[now]-sum-1)/k+1)*k+sum; 16 while(now<=m&&a[now]<=r) { 17 sum++; 18 now++; 19 } 20 ans++; 21 } 22 printf("%d\n",ans); 23 }
D:Tokitsukaze, CSL and Stone Game
博弈果断一点不会。分析:
首先判断先手必败的条件
1、有三堆及以上数量相等的石头,即 x x x
2、有两对及以上两堆数量相等的石头,即 x x y y
3、有两堆及以上的空堆 ,即 0 0 0
4、有相等的堆且存在数量减一的堆,即 x x x-1
除了以上情况,最后会变成这样的状态 (先手必胜)
0 1 2 3 …… n-1
所以判断形成这样的步数的奇偶即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+10; 5 6 int n,a[maxn]; 7 map<int,int> mp; 8 9 int main() { 10 scanf("%d",&n); 11 int ok=1; 12 for(int i=1;i<=n;i++) { 13 scanf("%d",&a[i]); 14 mp[a[i]]++; 15 ok&=(mp[a[i]]<=2); // x x x 16 } 17 int cnt=0; 18 map<int,int>::iterator it; 19 for(it=mp.begin();it!=mp.end();it++) { 20 if(it->second>=2) cnt++; // x x y y 21 } 22 ok&=(cnt<=1); 23 for(it=mp.begin();it!=mp.end();it++) { 24 if(it->second==2) { 25 ok&=(mp.count(it->first-1)==0); // x x x-1 26 if(it->first==0) ok=0; // 0 0 27 } 28 } 29 if(!ok) return 0*puts("cslnb"); 30 // 0 1 2 3 …… n-1 31 sort(a+1,a+n+1); 32 ll s=0; 33 for(int i=1;i<=n;i++) { 34 s+=a[i]-(i-1); 35 } 36 s%=2; 37 return 0*puts(s?"sjfnb":"cslnb"); 38 }
E:Tokitsukaze and Duel
分析:
先手如果第一步不能获胜,以后就不可能获胜。
后手如果第一步不能获胜,以后也不可能获胜,因为对方可以反转相同的维持局面。
先手获胜:可以通过前缀和预处理出先手是否必胜。
如果后手想要获胜,那么
1、k != 1 无限跳转
2、2*k >= n 因为到后手必定有一段连续的k个0或1,如果后手能获胜,必须能覆盖掉整个串
然后先手若不能第一步获胜,他必定会取中间的k个连续位置,所以要处理左右两个区间a、b
int len = n - k - 1;
a[1]==a[n] || a[len] == a[len+1] || a[n-len] == a[n-len+1] 时 后手也不能获胜
不是太懂,画图。。。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+10; 5 6 int n,k,a[maxn],sum[maxn]; 7 8 int query(int l,int r) { 9 if(l>r) return 0; 10 return sum[r]-sum[l-1]; 11 } 12 13 bool check1() { 14 for(int i=1;i+k-1<=n;i++) { 15 int tmp=query(1,i-1)+query(i+k,n); 16 if(tmp==0||tmp+k==n) return true; 17 } 18 return false; 19 } 20 21 bool check2() { 22 if(k==1||2*k<n) return false; 23 int len=n-k-1; 24 for(int i=2;i<=len;i++) { 25 if(a[i]!=a[i-1]||a[n-i+1]!=a[n-i+2]) return false; 26 } 27 if(a[1]==a[n]||a[len]==a[len+1]||a[n-len]==a[n-len+1]) return false; 28 return true; 29 } 30 31 int main() { 32 scanf("%d%d",&n,&k); 33 for(int i=1;i<=n;i++) scanf("%1d",&a[i]); 34 for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; 35 if(check1()) puts("tokitsukaze"); 36 else if(check2()) puts("quailty"); 37 else puts("once again"); 38 return 0; 39 }