zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    高级特性(4)- 数据库编程
    UVA Jin Ge Jin Qu hao 12563
    UVA 116 Unidirectional TSP
    HDU 2224 The shortest path
    poj 2677 Tour
    【算法学习】双调欧几里得旅行商问题(动态规划)
    南洋理工大学 ACM 在线评测系统 矩形嵌套
    UVA The Tower of Babylon
    uva A Spy in the Metro(洛谷 P2583 地铁间谍)
    洛谷 P1095 守望者的逃离
  • 原文地址:https://www.cnblogs.com/Dup4/p/10332497.html
Copyright © 2011-2022 走看看