CF#534 Div2

本来都是挺简单的题,D和E都做过类似的题目,但是发挥还是不太理想

怎么说呢 感觉还是熟能生巧吧 希望自己能在寒假的比赛中有一个稳定的发挥吧

菜是原罪

 

A. Splitting into digits

 

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 int n;
 5 int main() {
 6     scanf("%d",&n);
 7     printf("%d\n",n);
 8     for (int i=1;i<n;i++) printf("1 ");
 9     printf("1\n");
10     return 0;
11 }
View Code

 

B.Game with string

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int L=100010;
 6 int top,cnt;
 7 char str[L];
 8 int stk[L];
 9 int main() {
10     scanf("%s",str);
11     int len=strlen(str);
12     for (int i=0;i<len;i++) {
13         if (!top||stk[top]!=str[i])
14             stk[++top]=str[i];
15         else
16             cnt++,top--;
17     }
18     if (cnt&1) printf("Yes\n");
19     else printf("No\n");
20     return 0;
21 }
View Code

 

C.Grid game

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int L=1001;
 6 char str[L]; int f1,f2;
 7 int main() {
 8     scanf("%s",str);
 9     int len=strlen(str);
10     for (int i=0;i<len;i++) {
11         if (str[i]=='0') {
12             if (!f1) f1=1,printf("1 1\n");
13             else f1=0,printf("3 1\n");
14         }
15         else {
16             f2++,printf("%d 2\n",f2);
17             if (f2==4) f2=0;
18         }
19     }
20     return 0;
21 }
View Code

 

D.Game with modulo

看到这个询问次数就想到了二分,但是如何二分呢

一开始将方向放在了质因数分解上面,想了大概二十分钟觉得一定不可行后换方向

考虑先排除模数是$2^{n}$的形式

这样每次查询$2^{n}$和$2^{n+1}$的结果就能得到模数所在的区间

而且能保证先单调增再单调减

再二分即可

 

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

 

E.Johnny Solving

这种选择俩个中的一个回答的问题一般都是不满足一种那么一定存在一定的性质可以方便地推出另一个

那么根据第一个问题直接做一棵dfs生成树即可

如果不存在足够长的路径,那么一定存在至少$k$个叶子节点

由于每个点度数至少为$3$可推出每个叶子一定有对应的长度不能被$3$整除的环

 

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 const int N=250001;
 5 const int M=1000001;
 6 int n,m,k,cnt,maxid,top;
 7 int first[N],nxt[M],to[M];
 8 int fa[N],dep[N],son[N],sta[N]; bool vis[N];
 9 void add(int a,int b) {
10     to[++cnt]=b;
11     nxt[cnt]=first[a];
12     first[a]=cnt;
13     return;
14 }
15 void dfs(int x) {
16     vis[x]=1;
17     if (dep[x]>dep[maxid]) maxid=x;
18     for (int i=first[x];i;i=nxt[i])
19         if (!vis[to[i]]&&to[i]!=fa[x]) {
20             fa[to[i]]=x,son[x]++;
21             dep[to[i]]=dep[x]+1;
22             dfs(to[i]);
23         }
24     return;
25 }
26 void out() {
27     for (int i=1;i<top;i++)
28         printf("%d ",sta[i]);
29     printf("%d\n",sta[top]),top=0;
30     return;
31 }
32 void path(int st,int ed) {
33     while(st!=ed)
34         sta[++top]=st,st=fa[st];
35     sta[++top]=ed;
36     return;
37 }
38 int main() {
39     scanf("%d%d%d",&n,&m,&k);
40     for (int a,b,i=1;i<=m;i++) {
41         scanf("%d%d",&a,&b);
42         add(a,b),add(b,a);
43     }
44     dep[1]=1,dfs(1);
45     if (dep[maxid]>=n/k) {
46         printf("PATH\n%d\n",dep[maxid]);
47         while(maxid!=1)
48             printf("%d ",maxid),maxid=fa[maxid];
49         printf("1\n");
50     }
51     else {
52         int t[3];
53         printf("CYCLES\n");
54         for (int i=1;k&&i<=n;i++)
55             if (!son[i]) {
56                 int tmp=0;
57                 for (int j=first[i];tmp<=2;j=nxt[j])
58                     if (to[j]!=fa[i]) t[++tmp]=to[j];
59                 if (dep[t[1]]>dep[t[2]]) swap(t[1],t[2]);
60                 if ((dep[i]-dep[t[1]]+1)%3!=0)
61                     printf("%d\n",dep[i]-dep[t[1]]+1),path(i,t[1]),out();
62                 else if ((dep[i]-dep[t[2]]+1)%3!=0)
63                     printf("%d\n",dep[i]-dep[t[2]]+1),path(i,t[2]),out();
64                 else
65                     printf("%d\n",dep[t[2]]-dep[t[1]]+2),path(t[2],t[1]),sta[++top]=i,out();
66                 k--;
67             }
68     }
69     return 0;
70 }
View Code

 

posted @ 2019-01-28 10:26  2018szb  阅读(85)  评论(0)    收藏  举报