A. Anton and Danik
Anton likes to play chess, and so does his friend Danik.
Once they have played n games in a row. For each game it's known who was the winner — Anton or Danik. None of the games ended with a tie.
Now Anton wonders, who won more games, he or Danik? Help him determine this.
The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of games played.
The second line contains a string s, consisting of n uppercase English letters 'A' and 'D' — the outcome of each of the games. The i-th character of the string is equal to 'A' if the Anton won the i-th game and 'D' if Danik won the i-th game.
If Anton won more games than Danik, print "Anton" (without quotes) in the only line of the output.
If Danik won more games than Anton, print "Danik" (without quotes) in the only line of the output.
If Anton and Danik won the same number of games, print "Friendship" (without quotes).
问字符串中是A多还是D多,亦或者是一样多的水题。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 signed main(void) 5 { 6 int n; cin >> n; 7 string s; cin >> s; 8 9 int t = 0; 10 11 for (auto i : s) 12 if (i == 'A') 13 ++t; 14 else 15 --t; 16 17 if (!t) 18 cout << "Friendship" << endl; 19 else if (t > 0) 20 cout << "Anton" << endl; 21 else 22 cout << "Danik" << endl; 23 }
B. Anton and Digits
Recently Anton found a box with digits in his room. There are k2 digits 2, k3 digits 3, k5 digits 5 and k6 digits 6.
Anton's favorite integers are 32 and 256. He decided to compose this integers from digits he has. He wants to make the sum of these integers as large as possible. Help him solve this task!
Each digit can be used no more than once, i.e. the composed integers should contain no more than k2 digits 2, k3 digits 3 and so on. Of course, unused digits are not counted in the sum.
The only line of the input contains four integers k2, k3, k5 and k6 — the number of digits 2, 3, 5 and 6 respectively (0 ≤ k2, k3, k5, k6 ≤ 5·106).
Print one integer — maximum possible sum of Anton's favorite integers that can be composed using digits from the box.
问用k2个2,k3个3,k5个5,k6个6,能组合出的32和256中最大的和。
贪心地优先组合256,然后尽可能多地组合32即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 signed main(void) 5 { 6 int a, b, c, d, t, ans; 7 cin >> a >> b >> c >> d; 8 9 t = min(a, min(c, d)); 10 ans = t * 256; 11 a -= t; 12 t = min(a, b); 13 ans += t * 32; 14 cout << ans << endl; 15 }
C. Anton and Making Potions
Anton is playing a very interesting computer game, but now he is stuck at one of the levels. To pass to the next level he has to prepare npotions.
Anton has a special kettle, that can prepare one potions in x seconds. Also, he knows spells of two types that can faster the process of preparing potions.
- Spells of this type speed up the preparation time of one potion. There are m spells of this type, the i-th of them costs bi manapoints and changes the preparation time of each potion to ai instead of x.
- Spells of this type immediately prepare some number of potions. There are k such spells, the i-th of them costs di manapoints and instantly create ci potions.
Anton can use no more than one spell of the first type and no more than one spell of the second type, and the total number of manapoints spent should not exceed s. Consider that all spells are used instantly and right before Anton starts to prepare potions.
Anton wants to get to the next level as fast as possible, so he is interested in the minimum number of time he needs to spent in order to prepare at least n potions.
The first line of the input contains three integers n, m, k (1 ≤ n ≤ 2·109, 1 ≤ m, k ≤ 2·105) — the number of potions, Anton has to make, the number of spells of the first type and the number of spells of the second type.
The second line of the input contains two integers x and s (2 ≤ x ≤ 2·109, 1 ≤ s ≤ 2·109) — the initial number of seconds required to prepare one potion and the number of manapoints Anton can use.
The third line contains m integers ai (1 ≤ ai < x) — the number of seconds it will take to prepare one potion if the i-th spell of the first type is used.
The fourth line contains m integers bi (1 ≤ bi ≤ 2·109) — the number of manapoints to use the i-th spell of the first type.
There are k integers ci (1 ≤ ci ≤ n) in the fifth line — the number of potions that will be immediately created if the i-th spell of the second type is used. It's guaranteed that ci are not decreasing, i.e. ci ≤ cj if i < j.
The sixth line contains k integers di (1 ≤ di ≤ 2·109) — the number of manapoints required to use the i-th spell of the second type. It's guaranteed that di are not decreasing, i.e. di ≤ dj if i < j.
Print one integer — the minimum time one has to spent in order to prepare n potions.
需要制造n瓶毒药(也许是饮料,不知道),制造一瓶需要x单位时间。现在有2类魔法,每类最多只能使用一种且一次。
魔法一:有m种,花费bi金钱,使得制造一瓶毒药的时间变成ai。
魔法二:有k种,花费di金钱,使得在0单位时间内制造ci瓶毒药。
先给出最多花费金钱,求最小完成时间。
对于每种魔法,按照花费从小到大排序后,花费大而效果差的一定没用,直接忽略即可。
筛出两个按照花费单调上升的魔法序列,从左向右枚举一种魔法的时候,根据最大金钱的限制,另一种魔法对应的最优决策一定是从右向左,维护两个指针即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 200005 5 #define int long long 6 7 typedef long long LL; 8 typedef pair<int, int> pr; 9 10 int n, m, k, c, s; 11 12 pr sp1[N]; int t1; 13 pr sp2[N]; int t2; 14 15 signed main(void) 16 { 17 cin >> n >> m >> k >> c >> s; 18 19 for (int i = 1; i <= m; ++i) 20 cin >> sp1[i].second; 21 22 for (int i = 1; i <= m; ++i) 23 cin >> sp1[i].first; 24 25 for (int i = 1; i <= k; ++i) 26 cin >> sp2[i].second; 27 28 for (int i = 1; i <= k; ++i) 29 cin >> sp2[i].first; 30 31 sp1[++m] = make_pair(0, c); 32 sp2[++k] = make_pair(0, 0); 33 34 sort(sp1 + 1, sp1 + 1 + m); 35 sort(sp2 + 1, sp2 + 1 + k); 36 37 t1 = t2 = 0; 38 39 for (int i = 1; i <= m; ++i)if (sp1[i].first <= s) 40 if (!t1 || sp1[i].second < sp1[t1].second)sp1[++t1] = sp1[i]; 41 42 for (int i = 1; i <= k; ++i)if (sp2[i].first <= s) 43 if (!t2 || sp2[i].second > sp2[t2].second)sp2[++t2] = sp2[i]; 44 45 if (sp1[t1].second <= 0)return puts("0"), 0; 46 if (sp2[t2].second >= n)return puts("0"), 0; 47 48 LL answer = 4e18 + 7; 49 50 for (int i = 1, j = t1; i <= t2; ++i) 51 { 52 while (j && sp1[j].first + sp2[i].first > s)--j; 53 54 if (j)answer = min(answer, (LL)sp1[j].second * (n - sp2[i].second)); 55 } 56 57 cout << answer << endl; 58 }
D. Anton and Chess
Anton likes to play chess. Also, he likes to do programming. That is why he decided to write the program that plays chess. However, he finds the game on 8 to 8 board to too simple, he uses an infinite one instead.
The first task he faced is to check whether the king is in check. Anton doesn't know how to implement this so he asks you to help.
Consider that an infinite chess board contains one white king and the number of black pieces. There are only rooks, bishops and queens, as the other pieces are not supported yet. The white king is said to be in check if at least one black piece can reach the cell with the king in one move.
Help Anton and write the program that for the given position determines whether the white king is in check.
Remainder, on how do chess pieces move:
- Bishop moves any number of cells diagonally, but it can't "leap" over the occupied cells.
- Rook moves any number of cells horizontally or vertically, but it also can't "leap" over the occupied cells.
- Queen is able to move any number of cells horizontally, vertically or diagonally, but it also can't "leap".
The first line of the input contains a single integer n (1 ≤ n ≤ 500 000) — the number of black pieces.
The second line contains two integers x0 and y0 ( - 109 ≤ x0, y0 ≤ 109) — coordinates of the white king.
Then follow n lines, each of them contains a character and two integers xi and yi ( - 109 ≤ xi, yi ≤ 109) — type of the i-th piece and its position. Character 'B' stands for the bishop, 'R' for the rook and 'Q' for the queen. It's guaranteed that no two pieces occupy the same position.
The only line of the output should contains "YES" (without quotes) if the white king is in check and "NO" (without quotes) otherwise.
在无限大的国际象棋棋盘上,给出白子King的位置,以及一些黑子的种类(后,车,象)和位置,求是否in check。注意棋子不能 越“子”强杀。
枚举王的8个方向,看最近的棋子是否符合这个方向即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 500005 5 #define inf 2e9 + 7 6 7 int n; 8 int tx; 9 int ty; 10 int vis[8]; 11 int dis[8]; 12 13 signed main(void) 14 { 15 cin >> n >> tx >> ty; 16 17 for (int i = 0; i < 8; ++i) 18 dis[i] = inf; 19 20 for (int i = 1; i <= n; ++i) 21 { 22 char c; int x, y; 23 cin >> c >> x >> y; 24 25 if (x == tx && y < ty && ty - y < dis[0]) 26 dis[0] = ty - y, vis[0] = (c == 'Q' || c == 'R'); 27 if (x == tx && y > ty && y - ty < dis[1]) 28 dis[1] = y - ty, vis[1] = (c == 'Q' || c == 'R'); 29 if (y == ty && x < tx && tx - x < dis[2]) 30 dis[2] = tx - x, vis[2] = (c == 'Q' || c == 'R'); 31 if (y == ty && x > tx && x - tx < dis[3]) 32 dis[3] = x - tx, vis[3] = (c == 'Q' || c == 'R'); 33 34 if (tx + ty == x + y && x < tx && tx - x < dis[4]) 35 dis[4] = tx - x, vis[4] = (c == 'Q' || c == 'B'); 36 if (tx + ty == x + y && x > tx && x - tx < dis[5]) 37 dis[5] = x - tx, vis[5] = (c == 'Q' || c == 'B'); 38 if (tx - ty == x - y && x < tx && tx - x < dis[6]) 39 dis[6] = tx - x, vis[6] = (c == 'Q' || c == 'B'); 40 if (tx - ty == x - y && x > tx && x - tx < dis[7]) 41 dis[7] = x - tx, vis[7] = (c == 'Q' || c == 'B'); 42 } 43 44 int answer = 0; 45 46 for (int i = 0; i < 8; ++i) 47 answer |= vis[i]; 48 49 puts(answer ? "YES" : "NO"); 50 }
E. Anton and Tree
Anton is growing a tree in his garden. In case you forgot, the tree is a connected acyclic undirected graph.
There are n vertices in the tree, each of them is painted black or white. Anton doesn't like multicolored trees, so he wants to change the tree such that all vertices have the same color (black or white).
To change the colors Anton can use only operations of one type. We denote it as paint(v), where v is some vertex of the tree. This operation changes the color of all vertices u such that all vertices on the shortest path from v to u have the same color (including v and u). For example, consider the tree
and apply operation paint(3) to get the following:
Anton is interested in the minimum number of operation he needs to perform in order to make the colors of all vertices equal.
The first line of the input contains a single integer n (1 ≤ n ≤ 200 000) — the number of vertices in the tree.
The second line contains n integers colori (0 ≤ colori ≤ 1) — colors of the vertices. colori = 0 means that the i-th vertex is initially painted white, while colori = 1 means it's initially painted black.
Then follow n - 1 line, each of them contains a pair of integers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi) — indices of vertices connected by the corresponding edge. It's guaranteed that all pairs (ui, vi) are distinct, i.e. there are no multiple edges.
Print one integer — the minimum number of operations Anton has to apply in order to make all vertices of the tree black or all vertices of the tree white.
在树上求最小的染色次数使得全树为一个颜色。
求出缩点后的树的直径,除以二上取整即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 500005; 5 6 int n; 7 int cnt; 8 int c[N]; 9 int bel[N]; 10 int dis[N]; 11 queue<int> que; 12 vector<int> to[N]; 13 vector<int> TO[N]; 14 15 void dfs(int u, int f) 16 { 17 bel[u] = cnt; 18 19 for (auto v : to[u]) 20 if (c[v] == c[u]) 21 if (v != f)dfs(v, u); 22 } 23 24 signed main(void) 25 { 26 cin >> n; 27 28 for (int i = 1; i <= n; ++i) 29 cin >> c[i]; 30 31 for (int i = 1; i < n; ++i) 32 { 33 int x, y; cin >> x >> y; 34 to[x].push_back(y); 35 to[y].push_back(x); 36 } 37 38 for (int i = 1; i <= n; ++i) 39 if (!bel[i])++cnt, dfs(i, -1); 40 41 for (int i = 1; i <= n; ++i) 42 { 43 int u = bel[i]; 44 for (auto j : to[i]) 45 { 46 int v = bel[j]; 47 if (u != v) 48 { 49 TO[u].push_back(v); 50 TO[v].push_back(u); 51 } 52 } 53 } 54 55 memset(dis, -1, sizeof(dis)); 56 57 dis[1] = 0, que.push(1); 58 59 while (!que.empty()) 60 { 61 int top = que.front(); que.pop(); 62 for (auto v : TO[top])if (dis[v] == -1) 63 dis[v] = dis[top] + 1, que.push(v); 64 } 65 66 int s = 1; 67 for (int i = 2; i <= cnt; ++i) 68 if (dis[i] > dis[s])s = i; 69 70 memset(dis, -1, sizeof(dis)); 71 72 dis[s] = 0, que.push(s); 73 74 while (!que.empty()) 75 { 76 int top = que.front(); que.pop(); 77 for (auto v : TO[top])if (dis[v] == -1) 78 dis[v] = dis[top] + 1, que.push(v); 79 } 80 81 int t = 1; 82 for (int i = 2; i <= cnt; ++i) 83 if (dis[i] > dis[t])t = i; 84 85 cout << (dis[t] + 1) / 2 << endl; 86 }
后记:貌似这次CF的题都很友(水)好(水)。
@Author: YouSiki