Mail.Ru Cup 2018 Round 3 Solution

A. Determine Line

Water.

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

 

B. Divide Candies

Solved.

题意:

有$n \cdot n 的网格,每个网格放的糖数是(i^2 + j^2), i, j 表示行列$

求有多少个格子上的糖数是$m的倍数$

思路:

因为$m很小,处理出m的每个余数所对应的数字个数,再加加乘乘就好了$

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

 

C. Pick Heroes

Solved.

题意:

有两支队伍,每支队伍$n个人,每个人要选一个英雄,一共有2 \cdot n 个英雄$

$两支队伍的人轮流选,但是有些英雄有对应关系,也就是说如果某一轮一个人选了其中一个$

$那么在下一轮他的对手将被强制选择另一个,每个英雄最多存在于一个对应关系中$

这里是交互题。

思路:

贪心选即可,注意自己先手的时候,尽量先贪心选有对应关系的大的那只,再从大往小取

后手的时候注意特判,自己可不可以选有对应关系的英雄,如果可以,那么就回到先手状态

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 2010
 5 #define pii pair <int, int>
 6 int n, m, t;
 7 vector <pii> v, p; 
 8 map <int, int> mp;
 9 int vis[N];
10 
11 int main()
12 {
13     while (scanf("%d%d", &n, &m) != EOF)
14     {
15         v.clear(); mp.clear(); p.clear();
16         memset(vis, 0, sizeof vis);
17         for (int i = 1, x; i <= 2 * n; ++i) 
18         {
19             scanf("%d", &x);
20             p.emplace_back(x, i);
21         }
22         for (int i = 1, x, y; i <= m; ++i)
23         {
24             scanf("%d%d", &x, &y);
25             mp[x] = y;
26             mp[y] = x;
27             v.emplace_back(x, y);
28         }
29         scanf("%d", &t);
30         for (auto &it : v) if (p[it.first - 1].first < p[it.second - 1].first) swap(it.first, it.second);
31         sort(p.begin(), p.end(), [](pii a, pii b) { return a.first > b.first; });   
32         if (t == 1)
33         {
34             int x;
35             for (auto &it : v)
36             {
37                 printf("%d\n", it.first);
38                 fflush(stdout);
39                 scanf("%d", &x);
40                 vis[it.first] = 1;
41                 vis[x] = 1;
42             }
43             for (int i = v.size() + 1, r = 0; i <= n; ++i)
44             {
45                 while (vis[p[r].second]) ++r;
46                 printf("%d\n", p[r].second);
47                 fflush(stdout); 
48                 scanf("%d", &x);
49                 vis[p[r].second] = 1;
50                 vis[x] = 1;
51             }
52         }
53         else
54         {
55             int x;
56             for (int i = 1, r1 = 0, r2 = 0; i <= n; ++i)
57             {
58                 scanf("%d", &x);
59                 vis[x] = 1; 
60                 if (mp.find(x) != mp.end() && vis[mp[x]] == 0) 
61                 {
62                     printf("%d\n", mp[x]);
63                     vis[mp[x]] = 1;
64                 }
65                 else
66                 {
67                     while (r1 < v.size() && vis[v[r1].first]) ++r1;
68                       if (r1 < v.size()) 
69                     {
70                         printf("%d\n", v[r1].first);
71                         vis[v[r1].first] = 1;
72                     }
73                     else
74                     {
75                         while (vis[p[r2].second]) ++r2;
76                         printf("%d\n", p[r2].second);
77                         vis[p[r2].second] = 1;
78                     }
79                 }
80                 fflush(stdout);
81             }
82         }
83         
84     }
85     return 0;
86 }
View Code

 

D. Decorate Apple Tree

Solved.

题意:

有一棵树,每个叶子要有一个颜色。

一个点被定义为好点,是在它的子树中每个叶子的颜色都不同。

求好点个数为$k的时候 k \in [1, n] 所需要的最小的颜色个数$

思路:

先处理出每个点的子树中有多少个叶子,再按从小到大排序,依次输出即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 int n;
 6 vector <int> G[N];
 7 
 8 int sze[N];
 9 void DFS(int u)
10 {
11     sze[u] = 0;
12     for (auto v : G[u]) 
13     {
14         DFS(v);
15         sze[u] += sze[v];
16     }
17     if (!sze[u]) sze[u] = 1;
18 }
19 
20 int main()
21 {
22     while (scanf("%d", &n) != EOF)
23     {
24         for (int i = 1; i <= n; ++i) G[i].clear();
25         for (int u = 2, v; u <= n; ++u)
26         {
27             scanf("%d", &v);
28             G[v].push_back(u);
29         } DFS(1);
30         sort(sze + 1, sze + 1 + n); 
31         for (int i = 1; i <= n; ++i) printf("%d%c", sze[i], " \n"[i == n]);
32     }
33     return 0;
34 }
View Code

 

E. Check Transcription

Unsolved.

题意:

给出一个01串,以及一个字符串,求找出两个小串$A, B$

$使得01串为0的位置填A, 为1的位置填B,最后组成的串为给出的字符串$

求存在多少个$pairs(A, B)$

 

F. Write The Contest

Unsolved.

 

G. Take Metro

Unsolved.

 

H. Detect Robots

Unsolved.

转载于:https://www.cnblogs.com/Dup4/p/10052143.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值