• Avito Cool Challenge 2018 Solution


    A. Definite Game

    签.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int a;
     7     while (scanf("%d", &a) != EOF)
     8     {
     9         [](int x) 
    10         {
    11             for (int i = x - 1; i >= 1; --i) if (x % i)
    12             {
    13                 printf("%d
    ", x - i);
    14                 return;
    15             }
    16             printf("%d
    ", x);
    17         }(a);
    18     }
    19     return 0;
    20 }
    View Code

    B. Farewell Party

    签。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 int n, a[N], b[N], cnt[N];
     6 vector <int> v[N];
     7 int ans[N];
     8 
     9 bool ok()
    10 {
    11     for (int i = 1; i <= n; ++i) if (!v[i].empty() && v[i].size() != i)
    12         return false;
    13     return true;
    14 }
    15 void solve()    
    16 {    
    17     int cnt = 0;
    18     for (int i = 1; i <= n; ++i) v[i].clear();
    19     for (int i = 1; i <= n; ++i) 
    20     {
    21         int id = n - a[i];
    22         if (v[id].size() == id) 
    23         {
    24             ++cnt;
    25             for (auto it : v[id]) ans[it] = cnt;
    26             v[id].clear();
    27         }
    28         v[id].push_back(i);
    29     }
    30     if (!ok())
    31     {
    32         puts("Impossible");
    33         return;
    34     }
    35     else
    36     {
    37         for (int i = 1; i <= n; ++i) if (!v[i].empty()) 
    38         {
    39             ++cnt;
    40             for (auto it : v[i])
    41                 ans[it] = cnt;
    42         }
    43         puts("Possible");
    44         for (int i = 1; i <= n; ++i) printf("%d%c", ans[i], " 
    "[i == n]);
    45     }
    46 }
    47 
    48 int main()
    49 {
    50     while (scanf("%d", &n) != EOF)
    51     {
    52         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    53         solve();
    54     }
    55     return 0;
    56 }
    View Code

    C. Colorful Bricks

    Upsolved.

    题意:

    有$一行n个方格,m种颜色,恰好有k个方块与它左边方块的颜色不同$

    求方案数

    思路:

    $dp[i][j] 表示到第i个方格,有j个方块与左边方块颜色不同的方案数$

    转移有

    $dp[i + 1][j] += dp[i][j]$

    $dp[i + 1][j + 1] += dp[i][j] * (m - 1)$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 2010
     6 const ll MOD = (ll)998244353;
     7 int n, m, k;
     8 ll f[N][N];
     9 
    10 int main()
    11 {
    12     while (scanf("%d%d%d", &n, &m, &k) != EOF)
    13     {
    14         memset(f, 0, sizeof f);
    15         f[1][0] = m;
    16         for (int i = 2; i <= n; ++i)
    17         { 
    18             for (int j = 0; j <= min(i - 2, k); ++j)
    19             {
    20                 f[i][j] = (f[i][j] + f[i - 1][j]) % MOD;
    21                 f[i][j + 1] = (f[i][j + 1] + f[i - 1][j] * (m - 1) % MOD) % MOD;          
    22             }
    23         }
    24         printf("%lld
    ", f[n][k]);
    25     }
    26     return 0;
    27 }
    View Code

    D. Maximum Distance

    Upsolved.

    题意:

    有一张图

    定义一条路径的长度的路径上边权最大值

    定义两点距离为两点之间最短路径

    有一些特殊点,要对所有特殊点求离它最远的特殊点

    思路:

    我们考虑一条边所连接的两个连通块里,如果这两个连通块里都有特殊点

    那么这条边的权值就可以用于更新特殊点的答案

    其实就是一个求最小生成树的过程,先按边权排序

    要注意的是不是求整个图的最小生成树,而是所有特殊点的最小生成树

    其实是最小瓶颈生成树.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 int n, m, k;
     6 struct node
     7 {
     8     int u, v, w;
     9     void scan() { scanf("%d%d%d", &u, &v, &w); }
    10     bool operator < (const node &other) const { return w < other.w; }
    11 }edge[N];
    12 
    13 int pre[N], cnt[N];
    14 int find(int x) { return pre[x] == 0 ? x : pre[x] = find(pre[x]); }
    15 int Kruskal()
    16 {
    17     sort(edge + 1, edge + 1 + m);
    18     for (int i = 1; i <= m; ++i)
    19     {
    20         int u = edge[i].u, v = edge[i].v, w = edge[i].w;
    21         int fu = find(u), fv = find(v); 
    22         if (fu == fv) continue;
    23         cnt[fv] += cnt[fu]; 
    24         pre[fu] = fv;
    25         if (cnt[fv] == k) return w;  
    26     }
    27 }
    28 
    29 int main()
    30 {
    31     while (scanf("%d%d%d", &n, &m, &k) != EOF)
    32     {
    33         memset(pre, 0, sizeof pre);
    34         memset(cnt, 0, sizeof cnt); 
    35         for (int i = 1, x; i <= k; ++i) scanf("%d", &x), cnt[x] = 1;
    36         for (int i = 1; i <= m; ++i) edge[i].scan();
    37         int res = Kruskal();
    38         for (int i = 1; i <= k; ++i) printf("%d%c", res, " 
    "[i == k]);
    39     }
    40     return 0;
    41 }
    View Code

    E. Missing Numbers

    Upsolved.

    题意:

    有$n个数,给出a_2, a_4 cdots a_n$

    $n是偶数,提供a_1, a_3 cdots a_{n - 1}$

    使得

    $所有前缀和都是平方数$

    思路:

    考虑$n = 2的时候$

    $我们令b^2 = a_1 + a_2$

    $a^2 = a_1$

    那么有

    $b^2 - a^2 = (b + a) cdot (b - a) = a_2$

    $我们将a_2 拆成 p cdot q 的形式$

    $令p >= q$

    $那么有  b + a = p, b - a = q$

    $解方程有 b = frac{p + q}{2}$

    $发现一限制条件 p, q的奇偶性要相同$

    $那么a_1 = (frac{p + q}{2})^2 - a_2$

    那么如果有多解 我们取$a_1最小的$

    $因为当n >= 2的情况也可以同样这样推下去,会发现前面的项越小越好$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 100010
     6 int n;
     7 ll x[N];
     8 vector <int> vec[N << 1];
     9 
    10 void init()
    11 {
    12     for (int i = 1; i <= 450; ++i)
    13         for (int j = i * i; j <= 200000; j += i)
    14             vec[j].push_back(i);
    15 }
    16     
    17 int main()
    18 {
    19     init();
    20     while (scanf("%d", &n) != EOF)
    21     {
    22         for (int i = 2; i <= n; i += 2) scanf("%lld", x + i);
    23         bool flag = true; 
    24         ll base = 0;
    25         for (int i = 1; i <= n; i += 2)
    26         {
    27             base += x[i + 1];
    28             int limit = sqrt(x[i + 1]);
    29             ll res = (ll)1e18; 
    30             ll p, q;
    31             for (auto j : vec[x[i + 1]])                
    32                 if ((j % 2) == ((x[i + 1] / j) % 2))
    33                 {    
    34                     p = j, q = (x[i + 1] / j);
    35                     ll tot = (p + q) / 2;
    36                     tot *= tot;
    37                     if (tot > base)
    38                         res = min(res, tot - base);
    39                 }
    40             if (res <= (ll)1e13) 
    41             {
    42                 x[i] = res;
    43                 base += res;
    44             }
    45             else
    46             {
    47                 flag = false;
    48                 break;
    49             }
    50         }
    51         if (!flag) puts("No");
    52         else
    53         {
    54             puts("Yes");
    55             for (int i = 1; i <= n; ++i)
    56                 printf("%lld%c", x[i], " 
    "[i == n]);
    57         }
    58     }
    59     return 0;
    60 }
    View Code
  • 相关阅读:
    flask的简单使用
    Android Studio 使用Lambda表达式
    安卓SDK更新 国内镜像站点记录
    REACT-NATIVE入门(环境搭建及HELLOWORLD)
    深入理解Android 读感(一)
    JNI初入手
    (转)c++ 中的using namespace std是什么意思,什么时候用
    (转)const char to LPCTSTR不能转化问题
    Git常用操作之add操作
    Git日志操作
  • 原文地址:https://www.cnblogs.com/Dup4/p/10332497.html
Copyright © 2020-2023  润新知