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\n", 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] << "\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 << "\n";
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], " \n"[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\n", 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", 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\n", 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.

 

posted @ 2018-11-20 12:46  Dup4  阅读(380)  评论(0编辑  收藏  举报