• Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3) Solution


    A. Kitchen Utensils

    Water.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 110
     5 int n, k, cnt[N];
     6 
     7 int main()
     8 {
     9     while (scanf("%d%d", &n, &k) != EOF)
    10     {
    11         memset(cnt, 0, sizeof cnt);
    12         for (int i = 1, x; i <= n; ++i) 
    13         {
    14             scanf("%d", &x);
    15             ++cnt[x];
    16         }
    17         int Max = 0;
    18         for (int i = 1; i <= 100; ++i) Max = max(Max, cnt[i] % k == 0 ? cnt[i] / k : cnt[i] / k + 1);
    19         int res = 0;
    20         for (int i = 1; i <= 100; ++i) if (cnt[i])
    21         {
    22             res += Max * k - cnt[i];
    23         }
    24         printf("%d
    ", res);
    25     }
    26     return 0;
    27 }
    View Code

    B. Personalized Cup

    Water.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define INF 0x3f3f3f3f
     5 #define N 110
     6 int pos[N], w[N], h[N], n;
     7 string s;
     8 
     9 void init()
    10 {
    11     memset(w, 0x3f, sizeof w);
    12     memset(h, 0x3f, sizeof h);
    13     memset(pos, -1, sizeof pos); 
    14     for (int i = 100; i >= 1; --i)
    15     {
    16         for (int j = 1; j <= i; ++j) if (i % j == 0)
    17         {
    18             int a = i / j, b = j;
    19             if (a > b) swap(a, b);
    20             if (a <= 5 && b <= 20 && a <= w[i]) 
    21             {
    22                 pos[i] = i;
    23                 w[i] = a;
    24                 h[i] = b; 
    25             }
    26             if (w[i + 1] < w[i])
    27             {
    28                 pos[i] = pos[i + 1];
    29                 w[i] = w[i + 1];
    30                 h[i] = h[i + 1];
    31             }
    32         }
    33     }
    34 }
    35 
    36 int main()
    37 {
    38     init();
    39     ios::sync_with_stdio(false);
    40     cin.tie(0);
    41     cout.tie(0);
    42     while (cin >> s)
    43     {
    44         n = s.size();
    45         cout << w[n] << " " << h[n] << "
    "; 
    46         int need = pos[n] - n;
    47         int must = need / w[n];
    48         int remind = need % w[n];
    49         for (int i = 1, pos = 0; i <= w[n]; ++i)
    50         {
    51             int j = 1;
    52             for (; j <= must; ++j) cout << "*";
    53             if (remind) cout << "*", ++j, --remind;
    54             for (; j <= h[n]; ++j) cout << s[pos++];
    55             cout << "
    ";
    56         }
    57     }
    58     return 0;
    59 }
    View Code

    C. Playing Piano

    Upsolved.

    思路:每一位枚举,记忆化搜索。$dp[i][j] 表示第i位放j是否可以$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 int n, a[N], res[N], dp[N][10];
     6 
     7 int DFS(int i, int num)
     8 {
     9     if (i > n) return 1;
    10     int &x = dp[i][num];
    11     if (x != -1) return x;
    12     if (a[i] > a[i - 1])
    13     {
    14         for (int j = num + 1; j <= 5; ++j) 
    15         {
    16             x = DFS(i + 1, j);
    17             if (x) return res[i] = j, x = 1;
    18         }
    19     }    
    20     else if (a[i] < a[i - 1])
    21     {
    22         for (int j = 1; j < num; ++j)
    23         {
    24             x = DFS(i + 1, j);
    25             if (x) return res[i] = j, x = 1;
    26         }
    27     }
    28     else
    29     {
    30         for (int j = 1; j <= 5; ++j) if (j != num)
    31         {
    32             x = DFS(i + 1, j);
    33             if (x)  return res[i] = j, x = 1;
    34         }
    35     }
    36     return x = 0;
    37 }
    38 
    39 int main()
    40 {
    41     while (scanf("%d", &n) != EOF)
    42     {
    43         memset(dp, -1, sizeof dp);
    44         a[0] = 0;
    45         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    46         if (DFS(1, 0)) for (int i = 1; i <= n; ++i) printf("%d%c", res[i], " 
    "[i == n]);
    47         else puts("-1");    
    48     }
    49     return 0;
    50 }
    View Code

    D. Barcelonian Distance

    Solved.

    题意:

    在一个二维平面中,有一条直线,有两点个点,只能走这条直线上或者方格线上,求两点最短路径

    思路:

    考虑每个点到直线上通过方格线走只有两种方式,即横着走,纵着走

    那么通过直线的方式即有四种

    还有一种直接是曼哈顿距离,取$Min$即可

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 const double eps = 1e-8;
     6 ll a, b, c, x[2], y[2];
     7 double xa[2], ya[2], xb[2], yb[2];
     8 
     9 double dis(double x1, double y1, double x2, double y2)
    10 {
    11     return sqrt((x1 - x2) * (x1 - x2) * 1.0 + (y1 - y2) * (y1 - y2) * 1.0);  
    12 }
    13 
    14 double calcx(ll y) 
    15 {
    16     return -(b * y + c) * 1.0  / a; 
    17 }
    18 
    19 double calcy(ll x)
    20 {
    21     return -(a * x + c) * 1.0  / b; 
    22 }
    23 
    24 int main()
    25 {
    26     while (scanf("%lld%lld%lld", &a, &b, &c) != EOF)
    27     {
    28         for (int i = 0; i < 2; ++i) scanf("%lld%lld", x + i, y + i);
    29         double res = abs(x[0] - x[1]) + abs(y[0] - y[1]); 
    30         xa[0] = x[0]; ya[0] = calcy(x[0]);
    31         xa[1] = calcx(y[0]); ya[1] = y[0];
    32         xb[0] = x[1]; yb[0] = calcy(x[1]);
    33         xb[1] = calcx(y[1]); yb[1] = y[1];
    34         for (int i = 0; i < 2; ++i)
    35         {
    36             for (int j = 0; j < 2; ++j)
    37             {
    38                 res = min(res, dis(x[0], y[0], xa[i], ya[i]) + dis(x[1], y[1], xb[j], yb[j]) + dis(xa[i], ya[i], xb[j], yb[j]));
    39             }
    40         }
    41         printf("%.15f
    ", res);
    42     }
    43     return 0;
    44 }
    View Code

    E. The Unbearable Lightness of Weights

    Upsolved.

    题意:

    有n个砝码,知道所有砝码的重量,但是不知道每个砝码和重量的对应关系,可以有一次询问,问用k个砝码组成总重量为m的方案,求最后你最多知道多少个砝码的具体重量

    思路:

    如果不同重量的砝码种类不超过2,直接输出n

    01背包求出拼成重量为w, 物品个数为k的方案数,然后对于每种重量的砝码枚举个数,当且仅当当前个数和数量只有唯一一种方式组成时,那么这个数量就是合法的,可以用来更新答案

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 110
     5 int n, sum, tot, a[N], dp[N * N][N], cnt[N], C[N][N];
     6 
     7 void init()
     8 {
     9     for (int i = 0; i <= 100; ++i) for (int j = 0; j <= i; ++j)
    10     {
    11         if (j == 0 || j == i) C[i][j] = 1;
    12         else C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
    13     }
    14 }
    15 
    16 void Run()
    17 {
    18     init();
    19     while (scanf("%d", &n) != EOF)
    20     {
    21         for (int i = 1; i <= n; ++i)
    22         {
    23             scanf("%d", a + i), sum += a[i], ++cnt[a[i]];
    24             if (cnt[a[i]] == 1) ++tot;
    25         }
    26         if (tot <= 2)
    27         {
    28             printf("%d
    ", n);
    29             continue;
    30         }
    31         dp[0][0] = 1;
    32         for (int i = 1; i <= n; ++i) 
    33         {
    34             for (int j = sum; j >= a[i]; --j) for (int k = 1; k <= n; ++k)
    35                 dp[j][k] += dp[j - a[i]][k - 1];
    36         }
    37         int res = 0; 
    38         for (int i = 1; i <= 100; ++i) if (cnt[i])
    39         {
    40             for (int j = 1; j <= cnt[i]; ++j)
    41             {
    42                 if (dp[i * j][j] == C[cnt[i]][j])
    43                     res = max(res, j);
    44             }
    45         }
    46         printf("%d
    ", res);
    47     }
    48 }
    49 
    50 int main()
    51 {
    52     #ifdef LOCAL
    53         freopen("Test.in", "r", stdin);
    54     #endif 
    55 
    56     Run();
    57     return 0;
    58 }
    View Code

    F. Vasya and Maximum Matching

    Unsolved.

    G. Chattering

    Unsolved.

  • 相关阅读:
    创业之路——学习JavaScript
    ASP.NET 登录身份验证 二 自定义模式(framework)
    权限系统思考
    工作流文献研究 1
    ASP.NET登录身份验证 一
    ERP 数据流层 Namsara v2.0 预告
    ORM 革命 —— 复兴 | ORM Revolution Revived
    我的程序设计之道
    细颗粒度的权限系统 理论探索
    一个企业系统,到底有多少可以形成框架?
  • 原文地址:https://www.cnblogs.com/Dup4/p/9988265.html
Copyright © 2020-2023  润新知