Codeforces Round #534 (Div. 2)

B. Game with string

题意:

给出一个字符串s只包括小写字母。当轮到一个玩家的时候,他可以选择两个连续且相等的字母并且删除它。当一个玩家没得删的时候他就输了。

题解:

乍一看有点懵,像dp,但是观察一下就发现输赢和顺序无关,只跟能组成相同的对数量有关,这个数量是一定的。那么我们用栈扫一遍就好了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <stack>
 6 
 7 using namespace std;
 8 const int maxn=1e5+100;
 9 char s[maxn];
10 int n;
11 stack<char>S;
12 int ans;
13 int main(){
14     scanf("%s",s);
15     n=strlen(s);
16     for(int i=0;i<n;i++){
17         if(!S.empty()&&S.top()==s[i]){
18             S.pop();
19             ans++;
20         }else{
21             S.push(s[i]);
22         }
23     }
24     if(ans%2){
25         printf("Yes\n");
26     }else{
27         printf("No\n");
28     }
29 return 0;
30 }
View Code

C. Grid game

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 const int maxn=1000+10;
 8 char s[maxn];
 9 int n;
10 int main(){
11     scanf("%s",s);
12     n=strlen(s);
13     int a=0,b=0;
14     for(int i=0;i<n;i++){
15         if(s[i]=='0'){
16             a=a%4+1;
17             printf("3 %d\n",a);
18         }else{
19             b=b%2+1;
20             printf("1 %d\n",b*2-1);
21         }
22     }
23 return 0;
24 }
View Code

D. Game with modulo

题意:交互题。

V和P要玩一个游戏,P有一些正整数a,V要用下面的问题来猜这个数字a。他可以问(x,y),P会回答他:

1.'x',如果x mod a >= y mod a

2.'y',如果 x mod a < y mod a

V需要在60次问题内猜到数字a。保证a<=1e9.

题解:

首先询问0,1。如果返回x,那么a一定是1.如果返回y那么去询问1 2如果返回y再询问2 4然后4 8,8 16。直到返回x,则证明a一定在x和y之间。然后二分[x,y]这个区间。

这种办法我也没想到,看了答案后可以推一下发现可以很容易推出y=2*x.

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 const int Max=1e9;
 8 
 9 string com;
10 
11 int main(){
12     while(cin>>com){
13         if(com=="end")break;
14         if(com=="mistake")break;
15         if(com=="start"){
16             char c;
17             printf("? 0 1\n");
18             fflush(stdout);
19             scanf(" %c",&c);
20             if(c=='x'){
21                 printf("! 1\n");
22                 fflush(stdout);
23                 continue;
24             }else{
25                 int x=1,y=2;
26                 printf("? %d %d\n",x,y);
27                 fflush(stdout);
28                 while(scanf(" %c",&c)){
29                     if(c=='x'){
30                         break;
31                     }
32                     x=y,y=2*y;
33                     printf("? %d %d\n",x,y);
34                     fflush(stdout);
35                 }
36                 int l=x,r=y;
37                 int ans=0;
38                 for(int j=1;j<=29;j++){
39                     int mid=l+(r-l)/2;
40                     printf("? %d %d\n",mid,r);
41                     fflush(stdout);
42                     scanf(" %c",&c);
43                     if(c=='x'){
44                         l=mid;
45                     }else{
46                         r=mid;
47                     }
48                 }
49                 printf("! %d\n",max(l,r));
50                 fflush(stdout);
51             }
52         }
53     }
54    // fflush(stdout);
55 return 0;
56 }
View Code

E. Johnny Solving

题意:

给出一张连通图,不存在自环和重边,有n个结点和m条边,每个点的度数至少为3,给出一个参数k,若存在长度大于等于n/k的路径,则输出PATH并将路径输出,若存在k个满足周长不被3整除的环,且每一个环都存在一个只属于只属于这个环的点则输出CYCLES,并将k个环输出。

题解:下面是翻译自官方题解。。

从1结点开始建dfs树,然后确定这颗生成树的深度为depth。如果深度最少为n/k,那么我们就可以打印从根结点到最深结点的路径。否则的话,在dfs树中至少存在k+1个叶子结点。(想一想为什么,其实比较显然,也很好证明)。现在考虑dfs树中的一个叶子结点v,这个叶子结点至少有两条反向边,我们定义这两条反向边连向的祖先为x和y。显然我们有三个环,x到v,y到v,和x到y加上v。他们的长度分别是d(v,x)+1,d(v,y)+1,和d(x,y)+2.  

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <vector>
  6 
  7 using namespace std;
  8 const int maxn=25e4+100;
  9 const int maxm=5e5+100;
 10 int head[maxn],Next[2*maxm],to[2*maxm];
 11 int n,m,sz,k,goal,cir;
 12 vector<int>path;
 13 void init(){
 14     sz=0;
 15     memset(head,-1,sizeof(head));
 16 }
 17 void add_edge(int a,int b){
 18     ++sz;
 19     to[sz]=b;Next[sz]=head[a];head[a]=sz;
 20 }
 21 int vis[maxn];
 22 bool find_path(int u,int fa){
 23     vis[u]=1;
 24     path.push_back(u);
 25     if(path.size()>goal)
 26         return true;
 27     for(int i=head[u];i!=-1;i=Next[i]){
 28         int v=to[i];
 29         if(vis[v])continue;
 30         if(find_path(v,u))
 31             return true;
 32     }
 33     path.pop_back();
 34     return false;
 35 }
 36 int depth[maxn];
 37 void dfs(int u,int fa){
 38     vis[u]=1;
 39     depth[u]=path.size();
 40     path.push_back(u);
 41     int flag=0;
 42     for(int i=head[u];i!=-1;i=Next[i]){
 43         int v=to[i];
 44         if(!vis[v]){flag=1;break;}
 45     }
 46     if(flag){
 47         for(int i=head[u];i!=-1;i=Next[i]){
 48             int v=to[i];
 49             if(!vis[v])
 50                 dfs(v,u);
 51         }
 52     }else{
 53         if(cir){
 54             cir--;
 55             int fax=-1,fay=-1;
 56             for(int i=head[u];i!=-1;i=Next[i]){
 57                 int v=to[i];
 58                 if(v==fa)continue;
 59                 if(fax==-1)fax=v;
 60                 else if(fay==-1){fay=v;break;}
 61             }
 62             if(depth[fax]<depth[fay])swap(fax,fay);
 63             int ori=-1;
 64             if((depth[u]-depth[fax]+1)%3)ori=fax;
 65             if((depth[u]-depth[fay]+1)%3)ori=fay;
 66             if(ori==-1){
 67                 printf("%d\n",depth[fax]-depth[fay]+2);
 68                 printf("%d ",u);
 69                 for(int i=depth[fax];i>=depth[fay];i--){
 70                     printf("%d ",path[i]);
 71                 }
 72                 printf("\n");
 73             }else{
 74                 printf("%d\n",depth[u]-depth[ori]+1);
 75                 for(int i=depth[u];i>=depth[ori];i--){
 76                     printf("%d ",path[i]);
 77                 }
 78                 printf("\n");
 79             }
 80         }
 81     }
 82     path.pop_back();
 83 }
 84 
 85 int main(){
 86     scanf("%d%d%d",&n,&m,&k);
 87     goal=n/k;
 88     if(n%k)goal++;
 89     init();
 90     for(int i=1;i<=m;i++){
 91         int u,v;
 92         scanf("%d%d",&u,&v);
 93         add_edge(u,v);
 94         add_edge(v,u);
 95     }
 96     if(find_path(1,0)){
 97         printf("PATH\n");
 98         printf("%d\n",path.size());
 99         for(int i=0;i<path.size();i++){
100             printf("%d ",path[i]);
101         }
102     }else{
103         cir=k;
104         memset(vis,0,sizeof(vis));
105         path.clear();
106         printf("CYCLES\n");
107         dfs(1,0);
108     }
109 return 0;
110 }
View Code

 

posted @ 2019-02-16 15:11  蒟蒻LQL  阅读(205)  评论(0编辑  收藏  举报