• Codeforces Round #534 (Div. 2) Solution


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

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

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

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

    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 }
    View Code
  • 相关阅读:
    最小生成树之算法记录【prime算法+Kruskal算法】【模板】
    hdoj 1869 六度分离【最短路径求两两边之间最长边】
    la3211
    codeforces round #414 div1+div2
    bzoj1823
    bzoj3112
    bzoj1061&&bzoj3256
    单纯形&&线性规划
    bzoj1494
    bzoj3105
  • 原文地址:https://www.cnblogs.com/Dup4/p/10306995.html
Copyright © 2020-2023  润新知