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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

 

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 }
View Code

 

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 }
View Code

 

posted @ 2019-07-16 23:03  Frontierone  阅读(140)  评论(0编辑  收藏  举报