Codeforces Round #287 (Div. 二) 题解
Amr is a young coder who likes music a lot. He always wanted to learn how to play music but he was busy coding so he got an idea.
Amr has n instruments, it takes ai days to learn i-th instrument. Being busy, Amr dedicated k days to learn how to play the maximum possible number of instruments.
Amr asked for your help to distribute his free days between instruments so that he can achieve his goal.
The first line contains two numbers n, k (1 ≤ n ≤ 100, 0 ≤ k ≤ 10 000), the number of instruments and number of days respectively.
The second line contains n integers ai (1 ≤ ai ≤ 100), representing number of days required to learn the i-th instrument.
In the first line output one integer m representing the maximum number of instruments Amr can learn.
In the second line output m space-separated integers: the indices of instruments to be learnt. You may output indices in any order.
if there are multiple optimal solutions output any. It is not necessary to use all days for studying.
4 10 4 3 1 2
4 1 2 3 4
5 6 4 3 1 1 2
3 1 3 4
1 3 4
0
In the first test Amr can learn all 4 instruments.
In the second test other possible solutions are: {2, 3, 5} or {3, 4, 5}.
In the third test Amr doesn't have enough time to learn the only presented instrument.
A:水题,排个序,水题贪心吧算是
/************************************************************************* > File Name: cf287a.cpp > Author: ALex > Mail: 405045132@qq.com > Created Time: 2015年01月23日 星期五 23时49分38秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; struct node { int day; int d; }aaa[110]; int cmp (node a, node b) { return a.day < b.day; } int main () { int n, k; while (~scanf("%d%d", &n, &k)) { for (int i = 1; i <= n; ++i) { scanf("%d", &aaa[i].day); aaa[i].d = i; } sort (aaa+ 1, aaa + n + 1, cmp); int cnt = 0; for (int i = 1; i <= n; ++i) { if (k - aaa[i].day >= 0) { k -= aaa[i].day; cnt++; } else { break; } } printf("%d\n", cnt); if (cnt == 0) { continue; } printf("%d", aaa[1].d); for (int i = 2; i <= cnt; ++i) { printf(" %d", aaa[i].d); } printf("\n"); } return 0; }
Amr loves Geometry. One day he came up with a very interesting problem.
Amr has a circle of radius r and center in point (x, y). He wants the circle center to be in new position (x', y').
In one step Amr can put a pin to the border of the circle in a certain point, then rotate the circle around that pin by any angle and finally remove the pin.
Help Amr to achieve his goal in minimum number of steps.
Input consists of 5 space-separated integers r, x, y, x' y' (1 ≤ r ≤ 105, - 105 ≤ x, y, x', y' ≤ 105), circle radius, coordinates of original center of the circle and coordinates of destination center of the circle respectively.
Output a single integer — minimum number of steps required to move the center of the circle to the destination point.
2 0 0 0 4
1
1 1 1 4 4
3
4 5 6 5 6
0
In the first sample test the optimal way is to put a pin at point (0, 2) and rotate the circle by 180 degrees counter-clockwise (or clockwise, no matter).
/************************************************************************* > File Name: cf287b.cpp > Author: ALex > Mail: 405045132@qq.com > Created Time: 2015年01月24日 星期六 00时05分53秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int main () { double r, x1, y1, x2, y2; while (~scanf("%lf%lf%lf%lf%lf", &r, &x1, &y1, &x2, &y2)) { double d = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); d = sqrt (d); printf("%d\n", (int)ceil(d / (2 * r))); } return 0; }
Amr bought a new video game "Guess Your Way Out!". The goal of the game is to find an exit from the maze that looks like a perfect binary tree of height h. The player is initially standing at the root of the tree and the exit from the tree is located at some leaf node.
Let's index all the leaf nodes from the left to the right from 1 to 2h. The exit is located at some node n where 1 ≤ n ≤ 2h, the player doesn't know where the exit is so he has to guess his way out!
Amr follows simple algorithm to choose the path. Let's consider infinite command string "LRLRLRLRL..." (consisting of alternating characters 'L' and 'R'). Amr sequentially executes the characters of the string using following rules:
- Character 'L' means "go to the left child of the current node";
- Character 'R' means "go to the right child of the current node";
- If the destination node is already visited, Amr skips current command, otherwise he moves to the destination node;
- If Amr skipped two consecutive commands, he goes back to the parent of the current node before executing next command;
- If he reached a leaf node that is not the exit, he returns to the parent of the current node;
- If he reaches an exit, the game is finished.
Now Amr wonders, if he follows this algorithm, how many nodes he is going to visit before reaching the exit?
Input consists of two integers h, n (1 ≤ h ≤ 50, 1 ≤ n ≤ 2h).
Output a single integer representing the number of nodes (excluding the exit node) Amr is going to visit before reaching the exit by following this algorithm.
1 2
2
2 3
5
3 6
10
10 1024
2046
A perfect binary tree of height h is a binary tree consisting of h + 1 levels. Level 0 consists of a single node called root, level h consists of 2h nodes called leaves. Each node that is not a leaf has exactly two children, left and right one.
Following picture illustrates the sample test number 3. Nodes are labeled according to the order of visit.
可以发现,如果相邻2个二进制位相异,那么多走了一个节点,如果相同,就多走了一颗子树,子树上节点数目也很好求(二叉树),于是我们只要对目标叶子节点的每一位进行访问,与上次走的方向比较,然后统计答案就可以了
/************************************************************************* > File Name: cf287c.cpp > Author: ALex > Mail: 405045132@qq.com > Created Time: 2015年01月24日 星期六 00时21分39秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int main () { int h; long long n; while(~scanf("%d%I64d", &h, &n)) { --n; long long ans = 0; int pre = 1; for (int i = 0; i < h; ++i) { int c; if (n & (1LL << (h - i - 1))) { c = 1; } else { c = 0; } if (c != ((pre + 1) & 1)) { ans += (1LL << (h - i)); } else { ++ans; } pre = c; } printf("%I64d\n", ans); } return 0; }
Amr doesn't like Maths as he finds it really boring, so he usually sleeps in Maths lectures. But one day the teacher suspected that Amr is sleeping and asked him a question to make sure he wasn't.
First he gave Amr two positive integers n and k. Then he asked Amr, how many integer numbers x > 0 exist such that:
- Decimal representation of x (without leading zeroes) consists of exactly n digits;
- There exists some integer y > 0 such that:
-
;
- decimal representation of y is a suffix of decimal representation of x.
-
As the answer to this question may be pretty huge the teacher asked Amr to output only its remainder modulo a number m.
Can you help Amr escape this embarrassing situation?
Input consists of three integers n, k, m (1 ≤ n ≤ 1000, 1 ≤ k ≤ 100, 1 ≤ m ≤ 109).
Print the required number modulo m.
1 2 1000
4
2 2 1000
45
5 3 1103
590
A suffix of a string S is a non-empty string that can be obtained by removing some number (possibly, zero) of first characters from S.
bin神教的,设dp[i][j][0] 表示后i位,对k取模为j,且还没出现过整除的情况的数目,dp[i][j][1]表示后i位,对k取模为j,且已经出现过整除的情况
最后统计即可
/************************************************************************* > File Name: cf287d.cpp > Author: ALex > Mail: 405045132@qq.com > Created Time: 2015年01月24日 星期六 12时10分19秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; long long dp[1010][110][2]; long long f[1010]; int main() { int n, k, m; while (~scanf("%d%d%d", &n, &k, &m)) { memset (dp, 0, sizeof(dp)); f[0] = 1; for (int i = 1; i <= n; ++i) { f[i] = (f[i - 1] * 10) % k; } dp[0][0][0] = 1; for (int i = 1; i <= n; ++i) { for (int j = 0; j < k; ++j) { for (int x = 0; x < 10; ++x) { if (i == n && x == 0) { continue; } int t = (f[i - 1] * x % k + j) % k; for (int sta = 0; sta < 2; ++sta) { int s = sta; if (t == 0 && (x != 0)) { s = 1; } dp[i][t][s] += dp[i - 1][j][sta]; dp[i][t][s] %= m; } } } } int ans = 0; for (int i = 0; i < k; ++i) { ans += dp[n][i][1]; ans %= m; } printf("%d\n", ans); } return 0; }
Breaking Good is a new video game which a lot of gamers want to have. There is a certain level in the game that is really difficult even for experienced gamers.
Walter William, the main character of the game, wants to join a gang called Los Hermanos (The Brothers). The gang controls the whole country which consists of n cities with m bidirectional roads connecting them. There is no road is connecting a city to itself and for any two cities there is at most one road between them. The country is connected, in the other words, it is possible to reach any city from any other city using the given roads.
The roads aren't all working. There are some roads which need some more work to be performed to be completely functioning.
The gang is going to rob a bank! The bank is located in city 1. As usual, the hardest part is to escape to their headquarters where the police can't get them. The gang's headquarters is in city n. To gain the gang's trust, Walter is in charge of this operation, so he came up with a smart plan.
First of all the path which they are going to use on their way back from city 1 to their headquarters n must be as short as possible, since it is important to finish operation as fast as possible.
Then, gang has to blow up all other roads in country that don't lay on this path, in order to prevent any police reinforcements. In case of non-working road, they don't have to blow up it as it is already malfunctional.
If the chosen path has some roads that doesn't work they'll have to repair those roads before the operation.
Walter discovered that there was a lot of paths that satisfied the condition of being shortest possible so he decided to choose among them a path that minimizes the total number of affected roads (both roads that have to be blown up and roads to be repaired).
Can you help Walter complete his task and gain the gang's trust?
The first line of input contains two integers n, m (2 ≤ n ≤ 105,
), the number of cities and number of roads respectively.
In following m lines there are descriptions of roads. Each description consists of three integers
x, y, z (1 ≤ x, y ≤ n,
) meaning that there is a road connecting cities number
x and y. If
z = 1, this road is working, otherwise it is not.
In the first line output one integer k, the minimum possible number of roads affected by gang.
In the following k lines output three integers describing roads that should be affected. Each line should contain three integers
x, y, z (1 ≤ x, y ≤ n,
), cities connected by a road and the new state of a road.
z = 1 indicates that the road between cities
x and y should be repaired and
z = 0 means that road should be blown up.
You may output roads in any order. Each affected road should appear exactly once. You may output cities connected by a single road in any order. If you output a road, it's original state should be different from z.
After performing all operations accroding to your plan, there should remain working only roads lying on some certain shortest past between city 1 and n.
If there are multiple optimal answers output any.
2 1 1 2 0
1 1 2 1
4 4 1 2 1 1 3 0 2 3 1 3 4 1
3 1 2 0 1 3 1 2 3 0
8 9 1 2 0 8 3 0 2 3 1 1 4 1 8 7 0 1 5 1 4 6 1 5 7 0 6 8 0
3 2 3 0 1 5 0 6 8 1
In the first test the only path is 1 - 2
In the second test the only shortest path is 1 - 3 - 4
In the third test there are multiple shortest paths but the optimal is 1 - 4 - 6 - 8
最后枚举每一条边,判断即可
/************************************************************************* > File Name: cf287e.cpp > Author: ALex > Mail: 405045132@qq.com > Created Time: 2015年01月24日 星期六 12时51分10秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 100010; const int inf = 0x3f3f3f3f; int dist[N]; int dp[N]; struct CODEFORCES { int E; int V; void clear() { V = -1; } }pre[N]; int head[N]; bool vis[N << 1]; bool vis_edge[N << 1]; int tot, n, m; struct node { int next; int to; int id; int sta; }edge[N << 1]; void addedge (int from, int to, int sta, int id) { edge[tot].id = id; edge[tot].to = to; edge[tot].sta = sta; edge[tot].next = head[from]; head[from] = tot++; } void spfa () { queue <int> qu; while (!qu.empty()) { qu.pop(); } memset (dist, inf, sizeof(dist)); memset (dp, 0, sizeof(dp)); for (int i = 1; i <= n; ++i) { pre[i].V = -1; } dist[1] = 0; qu.push (1); while (!qu.empty()) { int u = qu.front(); qu.pop(); for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (dist[v] > dist[u] + 1) { dist[v] = dist[u] + 1; pre[v].V = u; pre[v].E = edge[i].id; if (edge[i].sta) { dp[v] = dp[u] + 1; } else { dp[v] = dp[u]; } qu.push (v); } else if (dist[v] == dist[u] + 1) { if (edge[i].sta) { if (dp[v] < dp[u] + 1) { dp[v] = dp[u] + 1; dist[v] = dist[u] + 1; pre[v].V = u; pre[v].E = edge[i].id; qu.push(v); } } else { if (dp[v] < dp[u]) { dp[v] = dp[u]; dist[v] = dist[u] + 1; pre[v].V = u; pre[v].E = edge[i].id; qu.push(v); } } } } } } void dfs (int u) { if (u == -1) { return; } dfs(pre[u].V); vis_edge[pre[u].E] = 1; } int main() { int u, v, w; while (~scanf("%d%d", &n, &m)) { memset (head, -1, sizeof(head)); memset (vis_edge, 0, sizeof(vis_edge)); memset (vis, 0, sizeof(vis)); tot = 0; for (int i = 1; i <= m; ++i) { scanf("%d%d%d", &u, &v, &w); addedge (u, v, w, i); addedge (v, u, w, i); } spfa (); dfs (n); int ans = 0; for (int u = 1; u <= n; ++u) { for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (!vis_edge[edge[i].id] && edge[i].sta && !vis[edge[i].id]) { ++ans; vis[edge[i].id] = 1; } else if (vis_edge[edge[i].id] && !edge[i].sta && !vis[edge[i].id]) { ++ans; vis[edge[i].id] = 1; } } } memset (vis, 0, sizeof(vis)); printf("%d\n", ans); for (int u = 1; u <= n; ++u) { for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (vis[edge[i].id]) { continue; } if (!vis_edge[edge[i].id] && edge[i].sta) { printf("%d %d 0\n", u, v); vis[edge[i].id] = 1; } else if (vis_edge[edge[i].id] && !edge[i].sta) { printf("%d %d 1\n", u, v); vis[edge[i].id] = 1; } } } } return 0; }