[关闭]
@Dmaxiya 2018-08-17T10:22:53.000000Z 字数 5287 阅读 1111

Educational Codeforces Round 31

Codeforces


Contests 链接:Educational Codeforces Round 31
过题数:4
排名:93/7946

A. Book Reading

题意

需要 秒才能看完一本书,接下来的 天时间里,第 天需要花 秒的时间工作,工作的时间不能看书。问她最少需要多少天才能看完书(每一天有 秒)。

输入

第一行有两个整数 ,第二行包含 个数字 。数据保证答案一定不大于

输出

输出 看完整本书需要的最少天数。

样例

输入 输出
2 2
86400 86398
2
2 86400
0 86400
1

题解

直接按题意模拟。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <bitset>
  16. #include <algorithm>
  17. #include <ctime>
  18. #include <functional>
  19. #include <iomanip>
  20. using namespace std;
  21. #define LL long long
  22. const int maxn = 100000 + 100;
  23. int n, t, tmp;
  24. int main() {
  25. #ifdef LOCAL
  26. freopen("test.txt", "r", stdin);
  27. // freopen("out.txt", "w", stdout);
  28. #endif
  29. ios::sync_with_stdio(false);
  30. while(scanf("%d%d", &n, &t) != EOF) {
  31. int ans = 0;
  32. for(int i = 1; i <= n; ++i) {
  33. scanf("%d", &tmp);
  34. t -= (86400 - tmp);
  35. if(t <= 0 && ans == 0) {
  36. ans = i;
  37. }
  38. }
  39. printf("%d\n", ans);
  40. }
  41. return 0;
  42. }

B. Japanese Crosswords Strike Back

题意

对一个长度为 串, 为其中连续的 的段数,第 段连续的 的个数为 ,例如 ,它的 就是 的集合为 。给定 以及 的值,判断是否只存在唯一的满足条件的 串。

输入

第一行为两个整数 ,第二行为 个整数

输出

如果只有唯一的 串满足条件,则输出 ,否则输出

样例

输入 输出
2 4
1 3
NO
3 10
3 3 2
YES
2 10
1 3
NO

题解

要判断只存在唯一的 串满足条件,只需要判断 这些连续的 的段以及段之间的间隔定为 是否正好等于 即可,即判断 是否为真。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <bitset>
  16. #include <algorithm>
  17. #include <ctime>
  18. #include <functional>
  19. #include <iomanip>
  20. using namespace std;
  21. #define LL long long
  22. const int maxn = 100;
  23. int n, k, tmp;
  24. int main() {
  25. #ifdef LOCAL
  26. freopen("test.txt", "r", stdin);
  27. // freopen("out.txt", "w", stdout);
  28. #endif
  29. ios::sync_with_stdio(false);
  30. while(scanf("%d%d", &n, &k) != EOF) {
  31. int sum = 0;
  32. for(int i = 0; i < n; ++i) {
  33. scanf("%d", &tmp);
  34. sum += tmp + 1;
  35. }
  36. if(sum == k + 1) {
  37. printf("YES\n");
  38. } else {
  39. printf("NO\n");
  40. }
  41. }
  42. return 0;
  43. }

C. Bertown Subway

题意

个城市,这个城市之间的道路满足以下两个条件:

  1. 对于第 个城市,都有唯一一条从这个城市出发的道路,这条道路的终点是 ,允许出现 的情况;
  2. 对于第 个城市,都有唯一一条到达这个城市的道路,这条道路的起点为

问在最多修改两条道路的情况下,使得有序对 的数量最多,如果图上存在从 的道路,则存在一个有序对

输入

第一行为一个整数 ,第二行为 个整数

输出

输出最多修改两条道路的情况下,图上最多的有序对数量。

样例

输入 输出 提示
3
2 1 3
9 可以将 改为 ,将 改为 ,这样就可以有 个有序对
5
1 5 4 3 2
17 可以将 改为 而将 改为

题解

对于按照题给方式生成的 序列,一定是一个 的排列,其中最多修改两条道路,相当于将排列中的两个环合并成一个环,由于有序对的数量等于环上节点数量的平方,所以应该将两个最多节点的环合并,如果只有一个环,则直接输出

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <bitset>
  16. #include <algorithm>
  17. #include <ctime>
  18. #include <functional>
  19. #include <iomanip>
  20. using namespace std;
  21. #define LL long long
  22. const int maxn = 100000 + 100;
  23. int n, x, cnt;
  24. int fa[maxn], num[maxn];
  25. LL ans[maxn], Ans;
  26. bool vis[maxn];
  27. void Init() {
  28. Ans = 0;
  29. cnt = 0;
  30. for(int i = 1; i <= n; ++i) {
  31. fa[i] = i;
  32. num[i] = 1;
  33. vis[i] = false;
  34. }
  35. }
  36. int Find(int x) {
  37. return (x == fa[x]? x: fa[x] = Find(fa[x]));
  38. }
  39. void unit(int x, int y) {
  40. int xx = Find(x);
  41. int yy = Find(y);
  42. if(xx != yy) {
  43. num[yy] += num[xx];
  44. fa[xx] = yy;
  45. }
  46. }
  47. int main() {
  48. #ifdef Dmaxiya
  49. freopen("test.txt", "r", stdin);
  50. // freopen("out.txt", "w", stdout);
  51. #endif //Dmaxiya
  52. ios::sync_with_stdio(false);
  53. while(scanf("%d", &n) != EOF) {
  54. Init();
  55. for(int i = 1; i <= n; ++i) {
  56. scanf("%d", &x);
  57. unit(x, i);
  58. }
  59. for(int i = 1; i <= n; ++i) {
  60. int f = Find(i);
  61. if(!vis[f]) {
  62. vis[f] = true;
  63. ans[cnt++] = num[f];
  64. }
  65. }
  66. if(cnt == 1) {
  67. printf("%I64d\n", ans[0] * ans[0]);
  68. continue;
  69. }
  70. sort(ans, ans + cnt);
  71. ans[cnt - 2] += ans[cnt - 1];
  72. for(int i = 0; i < cnt - 1; ++i) {
  73. Ans += ans[i] * ans[i];
  74. }
  75. printf("%I64d\n", Ans);
  76. }
  77. return 0;
  78. }

D. Boxes And Balls

题意

个箱子,最初在第 个箱子里有 种颜色的球,第 种颜色的球的个数为 ,其他的箱子都是空的,可以通过以下的操作将第 种颜色的求放入编号为 的箱子里:

  1. 选择任意一个非空的箱子,将其中的所有的球从箱子里取出;
  2. 选择 个空着的箱子(刚刚被取出球的箱子也可以被包括在其中),将刚刚取出的所有球分配到想分配的箱子中, 可以为 或者

某次操作的代价是从箱子中取出的球的总个数,而所有操作的代价等于每次操作的代价的和。问要将第 个箱子中的所有的球都放到相应的箱子中,最少需要多少代价。

输入

第一行为一个整数 ,第二行为 个整数

输出

输出最少需要的代价。

样例

输入 输出
3
1 2 3
6
4
2 3 4 5
19

题解

可以从另一个方向考虑这个问题:将 个球分到 个箱子里使得第 个箱子里的球的个数等于 ,每次只能拆成 个或者 个数字,每次拆的花费为 表示被拆的数字,画出这棵树就可以发现这是一棵哈夫曼树,每个节点的子节点数为 ,如果 为偶数,只要再加一个 的节点即可。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cfloat>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <list>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <bitset>
  16. #include <algorithm>
  17. #include <ctime>
  18. #include <functional>
  19. #include <iomanip>
  20. using namespace std;
  21. #define LL long long
  22. struct Node {
  23. LL num;
  24. Node() {}
  25. Node(LL n) {
  26. num = n;
  27. }
  28. };
  29. bool operator<(const Node &a, const Node &b) {
  30. return a.num > b.num;
  31. }
  32. priority_queue<Node> que;
  33. int n;
  34. LL num;
  35. int main() {
  36. #ifdef LOCAL
  37. freopen("test.txt", "r", stdin);
  38. // freopen("out.txt", "w", stdout);
  39. #endif
  40. ios::sync_with_stdio(false);
  41. while(scanf("%d", &n) != EOF) {
  42. if(n == 1) {
  43. scanf("%I64d", &num);
  44. printf("0\n");
  45. continue;
  46. } else if(n == 2) {
  47. scanf("%I64d", &num);
  48. LL tmp;
  49. scanf("%I64d", &tmp);
  50. printf("%I64d", tmp + num);
  51. continue;
  52. }
  53. LL ans = 0;
  54. while(!que.empty()) {
  55. que.pop();
  56. }
  57. if(n % 2 == 0) {
  58. que.push(Node(0));
  59. }
  60. for(int i = 0; i < n; ++i) {
  61. scanf("%I64d", &num);
  62. que.push(Node(num));
  63. }
  64. while(que.size() != 1) {
  65. Node tmp1 = que.top();
  66. que.pop();
  67. Node tmp2 = que.top();
  68. que.pop();
  69. Node tmp3 = que.top();
  70. que.pop();
  71. Node tmp4(tmp1.num + tmp2.num + tmp3.num);
  72. ans += tmp4.num;
  73. que.push(tmp4);
  74. }
  75. printf("%I64d\n", ans);
  76. }
  77. return 0;
  78. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注