• Codeforces Round #532 (Div. 2) Solution


    A. Roman and Browser

    签到.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n, k, a[110];
     5 
     6 int get(int b)
     7 {
     8     int vis[110];
     9     memset(vis, 0, sizeof vis);
    10     int c = b; 
    11     while (c <= n)
    12     {
    13         vis[c] = 1;
    14         c += k;
    15     }
    16     c = b - k;
    17     while (c >= 1)
    18     {
    19         vis[c] = 1;
    20         c -= k;
    21     }
    22     int l = 0, r = 0;
    23     for (int i = 1; i <= n; ++i) if (!vis[i])
    24     {
    25         if (a[i] == 1) ++l;
    26         else ++r;
    27     }
    28     return abs(l - r);
    29 }
    30 
    31 int main()
    32 {
    33     while (scanf("%d%d", &n, &k) != EOF)
    34     {
    35         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    36         int res = 0;
    37         for (int i = 1; i <= n; ++i) res = max(res, get(i));
    38         printf("%d
    ", res);
    39     }
    40     return 0;
    41 }
    View Code


    B. Build a Contest

    签到.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 int n, m, a[N];
     6 int cnt[N]; 
     7 
     8 int main()
     9 {
    10     while (scanf("%d%d", &n, &m) != EOF)
    11     {
    12         for (int i = 1; i <= m; ++i) scanf("%d", a + i);
    13         int need = n;
    14         memset(cnt, 0, sizeof cnt);
    15         for (int i = 1; i <= m; ++i)
    16         {
    17             if (cnt[a[i]] == 0)
    18                 --need;
    19             ++cnt[a[i]];
    20             if (need) putchar('0');
    21             else
    22             {
    23                 putchar('1');
    24                 for (int j = 1; j <= n; ++j) 
    25                 {
    26                     --cnt[j];
    27                     if (!cnt[j])
    28                         ++need;
    29                 }
    30             }
    31         }
    32         puts("");
    33     }
    34     return 0;
    35 }
    View Code

    C. NN and the Optical Illusion

    签到.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const double eps = 1e-8;
     5 const double PI = acos(-1.0);
     6 
     7 int main()
     8 {
     9     int n; double r;
    10     while (scanf("%d%lf", &n, &r) != EOF)
    11     {
    12         double ang1 = 2.0 * PI / n;
    13         double ang2 = (PI - ang1) / 2;
    14         double R = (r * sin(ang1) * 1.0) / (2 * sin(ang2) - sin(ang1));
    15         printf("%.10f
    ", R);
    16     }
    17     return 0;
    18 }
    View Code

    D. Dasha and Chess

    Upsolved.

    题意:

    你有一个白王,对方有$666$个黑王

    你每次可以八个方向走一步,对方可以任意移动一个黑王的位置

    在$2000步以内如果你和某个黑王同行同列,你就赢了$

    $给出你必胜的方案$

    思路:

    先走到中间,再考虑黑王个数最少的那个角落,向它的反方向走就可以了

    考虑最差的情况,四个角很平均都有$166个左右$

    那么也就是说另外三个角的个数加起来至少是$500个,而从中间走到某一角落只需要499步$

    所以一定可以包围一个

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 1010
     5 #define pii pair <int, int>
     6 #define x first
     7 #define y second
     8 int G[N][N], x, y, cnt[4];
     9 pii cor[N];
    10 
    11 void Move(int edx, int edy)
    12 {
    13     while (x != edx || y != edy)
    14     {
    15         if (x < edx && G[x + 1][y] == 0) ++x;
    16         else if (x > edx && G[x - 1][y] == 0) --x;
    17         if (y < edy && G[x][y + 1] == 0) ++y;
    18         else if (y > edy && G[x][y - 1] == 0) --y;
    19         printf("%d %d
    ", x, y);
    20         fflush(stdout);
    21         int k, a, b;
    22         scanf("%d%d%d", &k, &a, &b);
    23         if (k == -1) exit(0);
    24         G[cor[k].x][cor[k].y] = 0;
    25         cor[k].x = a, cor[k].y = b;
    26         G[cor[k].x][cor[k].y] = 1;
    27     }
    28 }
    29 
    30 int main()
    31 {
    32     while (scanf("%d%d", &x, &y) != EOF)
    33     {
    34         memset(G, 0, sizeof G);
    35         for (int i = 1; i <= 666; ++i)
    36         {
    37             scanf("%d%d", &cor[i].x, &cor[i].y);
    38             G[cor[i].x][cor[i].y] = 1;
    39         }
    40         Move(500, 500);
    41         memset(cnt, 0, sizeof cnt);
    42         for (int i = 1; i <= 999; ++i)
    43             for (int j = 1; j <= 999; ++j)
    44                 if (G[i][j])
    45                 {
    46                     if (i < x && j < y) ++cnt[0];
    47                     else if (i < x && j > y) ++cnt[1];
    48                     else if (i > x && j < y) ++cnt[2];
    49                     else ++cnt[3];
    50                 }
    51         if (cnt[0] <= 166) Move(999, 999);
    52         else if (cnt[1] <= 166) Move(999, 1);
    53         else if (cnt[2] <= 166) Move(1, 999);
    54         else Move(1, 1);
    55     }
    56     return 0;
    57 }
    View Code

    E. Andrew and Taxi

    Upsolved.

    题意:

    给出一张有向图,求改变一些边使得它没有环

    改变一条边的花费是它的边权,要使得最大花费最小

    输出最大花费和需要改变的边数

    再输出相应的边

    思路:

    先二分答案,每次check的时候检查一下边权大于limit的边组成的图是否有环

    如果有环,那么一定不行,如果没有环,那么一定可以

    对于剩下的边,方向自定,拓扑序小的连向拓扑序大的

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 int n, m;
     6 struct Graph
     7 {
     8     struct node
     9     {
    10         int to, nx, w, id;
    11         node() {}
    12         node (int to, int nx, int w, int id) : to(to), nx(nx), w(w), id(id) {}
    13     }a[N << 1];
    14     int head[N], pos;
    15     void init()
    16     {
    17         memset(head, 0, sizeof head);
    18         pos = 0;
    19     }
    20     void add(int u, int v, int w, int id) 
    21     {
    22         a[++pos] = node(v, head[u], w, id); head[u] = pos;
    23     }
    24 }G;
    25 #define erp(u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w, id = G.a[it].id; it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w, id = G.a[it].id)
    26 
    27 int degree[N], ord[N];
    28 bool check(int x)
    29 {
    30     memset(degree, 0, sizeof degree);
    31     for (int i = 1; i <= n; ++i) erp(i) if (w > x)
    32         ++degree[v];
    33     int cnt = 0;
    34     queue <int> q;
    35     for (int i = 1; i <= n; ++i) if (!degree[i])
    36         q.push(i);
    37     while (!q.empty())
    38     {
    39         ++cnt;
    40         int u = q.front(); q.pop();
    41         ord[u] = cnt;
    42         erp(u) if (w > x && --degree[v] == 0)
    43             q.push(v);
    44     }
    45     return cnt >= n;
    46 }
    47 
    48 int main()
    49 {
    50     while (scanf("%d%d", &n, &m) != EOF)
    51     {
    52         G.init();
    53         for (int i = 1, u, v, w; i <= m; ++i)
    54         {
    55             scanf("%d%d%d", &u, &v, &w);
    56             G.add(u, v, w, i);
    57         }
    58         int l = 0, r = (int)1e9, res = -1;
    59         while (r - l >= 0)
    60         {
    61             int mid = (l + r) >> 1;
    62             if (check(mid))
    63             {
    64                 res = mid;
    65                 r = mid - 1;
    66             }            
    67             else
    68                 l = mid + 1;
    69         }
    70         vector <int> vec;
    71         check(res);
    72         for (int i = 1; i <= n; ++i) erp(i) if (w <= res && ord[i] > ord[v]) vec.push_back(id);
    73         printf("%d %d
    ", res, (int)vec.size());
    74         for (int i = 0, len = vec.size(); i < len; ++i) printf("%d%c", vec[i], " 
    "[i == len - 1]);
    75     }
    76     return 0;
    77 }
    View Code

    F. Ivan and Burgers

    Upsolved.

    题意:

    询问区间任意数异或最大值

    思路:

    维护前缀线性基,但是要注意将$位置id大的数更换基底$

    $因为这样这些基底被用户更新答案的概率就更高$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 500010
     5 int n, q, c[N];
     6 int pos[N][25], p[N][25];
     7 
     8 void work(int x)
     9 {
    10     for (int i = 0; i <= 20; ++i) 
    11     {
    12         pos[x][i] = pos[x - 1][i];
    13         p[x][i] = p[x - 1][i];
    14     }
    15     int tmp = c[x];
    16     int id = x;
    17     for (int i = 20; i >= 0; --i)
    18     {
    19         if ((tmp >> i) & 1)
    20         {
    21             if (!p[x][i])
    22             {
    23                 p[x][i] = tmp;
    24                 pos[x][i] = id;
    25                 return; 
    26             }
    27             if (pos[x][i] < id)  
    28             {
    29                 swap(tmp, p[x][i]);
    30                 swap(id, pos[x][i]); 
    31             }
    32             tmp ^= p[x][i];
    33         }
    34     }
    35 }
    36 
    37 int ask(int l, int r)
    38 {
    39     int res = 0;
    40     for (int i = 20; i >= 0; --i) if (pos[r][i] >= l && (res ^ p[r][i]) > res)
    41         res ^= p[r][i];
    42     return res;
    43 }
    44 
    45 int main()
    46 {
    47     while (scanf("%d", &n) != EOF)
    48     {
    49         for (int i = 1; i <= n; ++i) scanf("%d", c + i);
    50         for (int i = 0; i < 25; ++i) pos[0][i] = p[0][i] = 0;
    51         for (int i = 1; i <= n; ++i) work(i);
    52         scanf("%d", &q);
    53         for (int qq = 1, l, r; qq <= q; ++qq)
    54         {
    55             scanf("%d%d", &l, &r);
    56             printf("%d
    ", ask(l, r));
    57         }
    58 
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    c#pda(wince)摄像头拍照程序
    单点登录在ASP.NET上的简单实现(图)
    写文件 指定固定开始位置
    关于"System.Web.HttpException: 超过了最大请求长度。"错误的解决
    配置本地YUM:
    开启mysql的审计功能
    用GRE通道连通机房之间的私网
    让nginx支持PATH_INFO
    Linux在本地使用yum安装软件
    sysbench的安装及使用
  • 原文地址:https://www.cnblogs.com/Dup4/p/10265069.html
Copyright © 2020-2023  润新知