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 }

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 }

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 }

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 }

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

时间: 2024-08-03 08:26:23

Mail.Ru Cup 2018 Round 3 Solution的相关文章

[题解]Mail.Ru Cup 2018 Round 1 - A. Elevator or Stairs?

[题目] A. Elevator or Stairs? [描述] Masha要从第x层楼去第y层楼找Egor,可以选择爬楼梯或者坐直升电梯.已知爬楼梯每层需要时间t1:坐直升电梯每层需要时间t2,直升电梯开门或者关门一次需要时间t3,当前直升电梯在第z层楼,直升电梯门是在关闭状态的.如果爬楼梯总时间严格小于坐直升电梯,则选择爬楼梯并输出YES,否则选择坐直升电梯并输出NO. 数据范围:1<=x,y,z,t1,t2,t3<=1000 [思路] 爬楼梯总时长:t1*abs(x-y) 坐直升电梯总时

[codeforces Mail.Ru Cup 2018 Round 1 D][ xor 操作]

http://codeforces.com/contest/1054/problem/D 题目大意:一个序列a1 a2...an,可以对若干个元素进行取反,使所得的新序列异或和为0的区间个数最多. 题目分析:首先易知每个位置的前缀异或和的值只有两种,因为对元素进行取反时,取偶数个元素异或和不变,奇数个元素就是原值取反.然后由于对一个位置取反,不会影响后面位置与这个位置的前缀异或和相同的位置个数(因为这个位置取反后,后面各个位置的前缀异或和也跟着改变),所以一个位置的改变只会影响与前面位置前缀和相

Mail.Ru Cup 2018 Round 1

A. Elevator or Stairs? 签. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int x, y, z, t[3]; 5 6 int main() 7 { 8 while (scanf("%d%d%d", &x, &y, &z) != EOF) 9 { 10 for (int i = 0; i < 3; ++i) scanf("%d", t +

Mail.Ru Cup 2018 Round 2 B. Alice and Hairdresser

传送门 待调bug https://paste.ubuntu.com/p/ZMzGkWMjkj/ 原文地址:https://www.cnblogs.com/violet-acmer/p/10916367.html

Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)C. Producing Snow+差分标记

题目链接:C. Producing Snow 题意:给两个数组v[N],T[N],v[i]表示第i天造的雪,T[i],表示第i天的温度,一堆雪如果<=T[i],当天就会融完,否则融化T[i],要求输出每天的融雪总量. 题解:我对T数组求个前缀和,就可以二分找到每堆雪在那一天(pos)融化,余下的要加进答案中ans[i],然后用一个an数组在a[i]+1,a[pos]-1,最后求再求一次前缀和. ans[i]再加上an[i]*t[i].每次操作二分logn,N次操作.复杂度O(nlogn) #in

Codeforces Round #472 (rated, Div. 2, based on VK Cup 2018 Round 2)

A. Tritonic Iridescence 题解:分类讨论.注意题目要求,至少有两种方案. 1 #pragma warning(disable:4996) 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 9 int n, m; 10 stri

Codeforces Round #472 (based on VK Cup 2018 Round 2)解题报告

A. Mystical Mosaic 题目大意: 给一个空白矩阵,每次可以选一些行和一些列并让他们的交点涂黑,每次选的行和列不能有交集. 给出最后的矩阵样子,问能不能经过若干次以上操作后得到最后的矩阵. 思路: 每一行都可以确定哪些列必须被覆盖记为Si,任意两个不同的行之间要么S相等要么相交为空集. 所以我们要做的就是确定任意两行,他们的S要么相等要么相交为空集,这是答案为Yes的充要条件. 代码: 1 #include <bits/stdc++.h> 2 using namespace st

Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) C. Stairs and Elevators【二分查找】

In the year of 30XX30XX participants of some world programming championship live in a single large hotel. The hotel has nn floors. Each floor has mm sections with a single corridor connecting all of them. The sections are enumerated from 11 to mm alo

【枚举】【二分】【推导】Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) D. Resource Distribution

题意:有两个服务要求被满足,服务S1要求x1数量的资源,S2要求x2数量的资源.有n个服务器来提供资源,第i台能提供a[i]的资源.当你选择一定数量的服务器来为某个服务提供资源后,资源需求会等量地分担给它们,要求每台服务器承担的资源需求不超过其所能提供的资源需求.给定一种合法的方案,每台服务器要么没有被分配给任何一个服务,或者被分配给其中一个服务. 对服务器按能提供的资源从小到大排序.枚举给S1分配的服务器数量i,然后在a数组中二分,就可以得到给S1提供的是哪i台服务器,它们占据了a数组中连续的