A. Splitting into digits
Solved.
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int n; 5 6 void solve() 7 { 8 printf("%d ", n); 9 for (int i = 1; i <= n; ++i) printf("%d%c", 1, " "[i == n]); 10 } 11 12 int main() 13 { 14 while (scanf("%d", &n) != EOF) 15 solve(); 16 return 0; 17 }
B. Game with string
Solved.
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 100010 5 char s[N]; 6 7 int main() 8 { 9 while (scanf("%s", s + 1) != EOF) 10 { 11 stack <char> sta; 12 int cnt = 0; 13 for (int i = 1, len = strlen(s + 1); i <= len; ++i) 14 { 15 if (!sta.empty() && sta.top() == s[i]) sta.pop(), ++cnt; 16 else sta.push(s[i]); 17 } 18 puts(cnt & 1 ? "Yes" : "No"); 19 } 20 return 0; 21 }
C. Grid game
Solved.
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1010 5 char s[N]; 6 7 int main() 8 { 9 while (scanf("%s", s + 1) != EOF) 10 { 11 int x = 0, y = 0; 12 for (int i = 1, len = strlen(s + 1); i <= len; ++i) 13 { 14 if (s[i] == '1') 15 { 16 printf("%d %d ", 1, x % 2 ? 3 : 1); 17 ++x; 18 } 19 else 20 { 21 printf("%d %d ", 3, y % 4 + 1); 22 ++y; 23 } 24 } 25 } 26 return 0; 27 }
D. Game with modulo
Solved.
题意:
交互题
猜数,猜一个$a$
每次询问格式为$(x, y)$
返回结果有两种
$x ;if (x ; mod; a) >= (y ;mod; a)$
$y ;if (x ;mod; a) < (y ;mod; a) $
思路:
我们考虑 从小到大倍增,去找到$a的一个单调范围$
比如说$1, 2, 4, 8, 16, 32 如果某一次询问中返回了x$
那么说明$a在询问的(x, y)范围中 并且2 cdot a 不在这个范围内$
因为是从小到大进行倍增
那么我们考虑某一次询问是$(x, 2cdot x)$
$a在其中$
$如果 a > x, 那么必然有x >= 2 cdot x - a$
$如果a = x 那么必然有 x ;mod;a = 2 cdot x ;mod; a$
那么这个区间就具有一个单调性,可以进行二分
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 char op[110]; 5 6 bool check(int x, int y) 7 { 8 printf("? %d %d ", x, y); 9 fflush(stdout); 10 scanf("%s", op); 11 return op[0] == 'y'; 12 } 13 14 void solve(int l, int r) 15 { 16 int base = 1; 17 for (int i = l; i <= r; i += base, base <<= 1) 18 { 19 printf("? %d %d ", i, i + base); 20 fflush(stdout); 21 scanf("%s", op); 22 if (op[0] == 'x') 23 { 24 int l = i + 1, r = i + base - 1, res = -1; 25 while (r - l >= 0) 26 { 27 int mid = (l + r) >> 1; 28 if (check(i, mid)) 29 { 30 l = mid + 1; 31 res = mid; 32 } 33 else 34 { 35 r = mid - 1; 36 } 37 } 38 if (res == -1) res = i; 39 printf("! %d ", res + 1); 40 fflush(stdout); 41 return; 42 } 43 } 44 45 } 46 47 int main() 48 { 49 while (scanf("%s", op) && op[0] != 'e') 50 solve(0, 1000000000); 51 return 0; 52 }
E. Johnny Solving
Upsolved.
题意:
给出一个无向图,没有重边和自环,每个点的度数至少是3
要求找出一个长度至少为$frac{n}{k}的简单路径$
或者找出$至少k个环,每个环的长度至少为3,并且环的长度不被3整除,并且环中有一个点只属于这个环$
思路:
首先跑一棵$DFS树,如果某个叶子结点的深度>= frac{n}{k} 那么直接输出这条简单路径$
$否则叶子结点个数肯定大于 k 个$
证明
$我们假设每个叶子结点到根节点的距离为x_1, x_2, cdots x_c$
那么$x_1 + x_2 + cdots + x_c >= n$
$那么根据抽屉原理 max(x_1, x_2, cdots x_c) >= frac{n}{c}$
$又 frac {n}{c} < frac{n}{k} 所以 c > k$
再考虑对于一个叶子结点u来说,它度数至少为$3$
$考虑 它的两条返祖边连向x, y 我们令deep[x] < deep[y]$
$那么这个时候有三个环 dist(x,u) + 1, dist(y, u) + 1, dist(x, y) + 2$
$首先证明三个环的长度都>= 3$
$因为没有重边,所以dist(x, u) 和 dist(y, u) >= 2 = 3 - 1$
$又x和y是不同的两点 所以 dist(x, y) >= 1 = 3 - 2$
$再证明三个环的长度至少有一个不被3整除$
$我们假设三个环的长度都被3整除,那么有$
$(dist(x, u) + 1) \% 3 == 0$
$(dist(y, u) + 1) \% 3 == 0$
$(dist(x, y) + 1) \% 3 == 0$
$又 dist(x, u) = (dist(y, u) + dist(x, y))$
$所以 dist(x, y) \% 3 == 0$
那么$(dist(x, y) + 2) \% 3 != 0$
$与已知矛盾, 得证$
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 300010 5 int n, m ,k; 6 vector <int> G[N]; 7 8 int fa[N], vis[N], deep[N], Max, pos; 9 void DFS(int u) 10 { 11 vis[u] = 1; 12 if (deep[u] > Max) 13 { 14 Max = deep[u]; 15 pos = u; 16 } 17 for (auto v : G[u]) if (!vis[v]) 18 { 19 fa[v] = u; 20 deep[v] = deep[u] + 1; 21 DFS(v); 22 } 23 } 24 25 vector < vector <int> > res; 26 int isleaf[N]; 27 void work(int u) 28 { 29 vis[u] = 1; 30 if (!isleaf[u]) 31 { 32 if (res.size() >= k) return; 33 int x = -1, y = -1; 34 for (auto v : G[u]) if (v != fa[u]) 35 { 36 if (x == -1) x = v; 37 else if (y == -1) y = v; 38 else break; 39 } 40 if (deep[x] > deep[y]) swap(x, y); 41 vector <int> tmp; int it = -1, top = -1; 42 if ((deep[u] - deep[y] + 1) % 3) 43 { 44 it = u; top = fa[y]; 45 } 46 else if ((deep[u] - deep[x] + 1) % 3) 47 { 48 it = u; top = fa[x]; 49 } 50 else 51 { 52 tmp.push_back(u); 53 it = y; top = fa[x]; 54 } 55 while (it != top) tmp.push_back(it), it = fa[it]; 56 res.push_back(tmp); 57 } 58 else for (auto v : G[u]) if (!vis[v]) work(v); 59 } 60 61 int main() 62 { 63 while (scanf("%d%d%d", &n, &m, &k) != EOF) 64 { 65 for (int i = 1; i <= n; ++i) G[i].clear(); 66 for (int i = 1, u, v; i <= m; ++i) 67 { 68 scanf("%d%d", &u, &v); 69 G[u].push_back(v); 70 G[v].push_back(u); 71 } 72 deep[1] = 1; Max = 1; 73 fa[1] = 0; 74 DFS(1); 75 if (Max > n / k) 76 { 77 puts("PATH"); 78 vector <int> res; 79 int it = pos; 80 while (it) 81 { 82 res.push_back(it); 83 it = fa[it]; 84 } 85 int len = res.size(); 86 printf("%d ", len); 87 for (int i = 0; i < len; ++i) printf("%d%c", res[i], " "[i == len - 1]); 88 } 89 else 90 { 91 puts("CYCLES"); 92 memset(vis, 0, sizeof vis); 93 memset(isleaf, 0, sizeof isleaf); 94 for (int i = 1; i <= n; ++i) isleaf[fa[i]] = 1; 95 work(1); 96 for (int i = 0; i < k; ++i) 97 { 98 auto it = res[i]; 99 int len = it.size(); 100 printf("%d ", len); 101 for (int j = 0; j < len; ++j) printf("%d%c", it[j], " "[j == len - 1]); 102 } 103 } 104 } 105 return 0; 106 }