zoukankan      html  css  js  c++  java
  • Mail.Ru Cup 2018 Round 1

    A. Elevator or Stairs?

    签.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int x, y, z, t[3];
     5 
     6 int main()
     7 {
     8     while (scanf("%d%d%d", &x, &y, &z) != EOF)
     9     {
    10         for (int i = 0; i < 3; ++i) scanf("%d", t + i);
    11         int a = (abs(z - x) + abs(x - y)) * t[1] + 3 * t[2];
    12         int b = abs(x - y) * t[0];
    13         puts(a <= b ? "YES" : "NO");
    14     }
    15     return 0;
    16 }
    View Code

    B. Appending Mex

    签.

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

    C. Candies Distribution

    Upsolved.

    题意:

    一个序列,$a_i取值为[1, n]$

    告诉你$每个数左边有多少数大于你,记为l_i$

    $右边有多少数大于你,记为r_i$

    让你还原出这个序列,如果没有合法的输出$NO$

    思路:

    $我们知道一个数的l_i + r_i 越大,那么这个数越小$

    $那我们不妨令 a_i = n - l_i - r_i$

    $再检查一遍即可$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 1010
     5 int n, l[N], r[N], v[N];
     6 
     7 int main()
     8 {
     9     while (scanf("%d", &n) != EOF)
    10     {
    11         for (int i = 1; i <= n; ++i) scanf("%d", l + i);
    12         for (int i = 1; i <= n; ++i) scanf("%d", r + i);
    13         for (int i = 1; i <= n; ++i) v[i] = n - l[i] - r[i];
    14         bool flag = true;
    15         for (int i = 1; i <= n; ++i) 
    16         {
    17             for (int j = 1; j < i; ++j)
    18                 if (v[j] > v[i])
    19                     --l[i];
    20             for (int j = i + 1; j <= n; ++j)
    21                 if (v[j] > v[i])
    22                     --r[i];
    23             if (l[i] != 0 || r[i] != 0)
    24             {
    25                 flag = false;
    26                 break;
    27             }
    28         }
    29         if (!flag) puts("NO");
    30         else
    31         {
    32             puts("YES");
    33             for (int i = 1; i <= n; ++i) 
    34                 printf("%d%c", v[i], " 
    "[i == n]);
    35         }
    36     }
    37     return 0;
    38 }
    View Code

    D. Changing Array

    Upsolved.

    题意:

    给一个序列,$可以将每个位置上的数取反$

    $求最多有多少子区间的异或和不为0$

    思路:

    求最多有多少子区间$异或和不为0,比较困难$

    $正难则反,我们考虑反面,我们求最少有多少个子区间异或和为0$

    $我们知道一段区间l, r的异或和是S_r oplus S_[l - 1]$

    $S表示前缀异或$

    $那么一个序列的前缀异或里面如果有x个a, 那么子区间异或为0的个数为frac{a cdot (a - 1)}{2}$

    $我们考虑 b = ~a, 而且a, b之间可以互相转化,并且只能互相转化,而不能转化为其他的数字$

    $令x = a的个数, y = b的个数$

    $我们令n = x + y $

    $那么a, b构成的子区间个数就是 frac{x cdot (x - 1)}{2} + frac{y cdot (y - 1)}{2}$

    $将n = x + y 代入$

    $就得到一个一元二次方程,取对称轴即可$

    $我们考虑转化都是oplus (1 << k) - 1$

    转化两次即相当于没有转化

    $所以每个前缀异或都能转化为自己想要的那个数$

    $为什么不考虑前面的数转化了会影响到后面的前缀异或?$

    $那后面那个如果受影响了,再转化回来不就好了?$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 200010
     6 int n, k;
     7 int a[N];
     8 map <int, int> mp;
     9 
    10 int main()
    11 {
    12     while (scanf("%d%d", &n, &k) != EOF)
    13     {
    14         mp.clear(); mp[0] = 1;
    15         int d = (1 << k) - 1;
    16         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    17         for (int i = 1; i <= n; ++i)
    18         {
    19             a[i] ^= a[i - 1];
    20             ++mp[a[i]];
    21             if (mp.find(a[i] ^ d) == mp.end()) mp[a[i] ^ d] = 0;
    22         }
    23         ll res = 0;
    24         for (auto it : mp) if (it.first > (it.first ^ d))
    25         {
    26             int a = it.second, n = a + mp[it.first ^ d];
    27             int b = n / 2;
    28             res += (1ll * n * n + 2ll * b * b - 2ll * b * n - n) / 2;
    29         }
    30         printf("%lld
    ", 1ll * n * (n + 1) / 2 - res);
    31     }
    32     return 0;
    33 }
    View Code
  • 相关阅读:
    DataTables中自增序号的实现
    MVC中调用模态框之后导致JS失效
    teamviewer13破解版
    屏幕录制专家破解版
    Navicat Premium 12 (内含破解补丁)
    Navicat新建连接出现10060 "Unknown error" 错误
    Windows添加永久路由
    VMware虚拟机下Linux网络配置——桥接模式
    文件基本属性
    ifconfig: command not found
  • 原文地址:https://www.cnblogs.com/Dup4/p/10354410.html
Copyright © 2011-2022 走看看