[关闭]
@Dmaxiya 2018-08-17T10:27:23.000000Z 字数 5095 阅读 1019

Codeforces Round #363 (Div. 2)

Codeforces


Contests 链接:Codeforces Round #363 (Div. 2)
过题数:4
排名:158/11417

A. Launch of Collider

题意

一个很大的原子对撞机,有 个原子同时发射,所有原子都被排列在一条直线上,它们的位置用一个 轴上的坐标 表示,每个原子所在的坐标都是一个偶数,每个原子都有一个初始的运动方向,它们的速度都是 ,问对撞机启动后,最早相互碰撞的原子的碰撞时间,如果所有原子都无法碰撞,则输出

数据范围

题解

根据给定的方向,如果相邻的两个原子运动方向相对,计算它们的撞击时间,对所有满足条件的原子计算时间取最小。

过题代码

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

B. One Bomb

题意

给定一个 的仓库,用一个字符串表示,"." 表示空地,"*" 表示墙,问能不能在仓库中的某个位置放置一个炸弹,使得这个炸弹能够炸掉所有的墙,炸弹可以放在空地上也可以放在墙上,且炸弹在炸毁一堵墙后不会停止,它会直接炸掉所有与其同一行与同一列的墙。

数据范围

题解

枚举放炸药的位置,然后 判断能否炸掉所有墙,总的时间复杂度是

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. #define LL long long
  20. const int maxn = 1000 + 100;
  21. struct Node {
  22. int x, y;
  23. };
  24. int n, m, ansx, ansy;
  25. bool f;
  26. char str[maxn][maxn];
  27. Node node[maxn * maxn];
  28. int main() {
  29. #ifdef LOCAL
  30. freopen("test.txt", "r", stdin);
  31. // freopen("out.txt", "w", stdout);
  32. #endif // LOCAL
  33. ios::sync_with_stdio(false);
  34. while(scanf("%d%d", &n, &m) != EOF) {
  35. int cnt = 0;
  36. f = false;
  37. for(int i = 0; i < n; ++i) {
  38. scanf("%s", str[i]);
  39. for(int j = 0; j < m; ++j) {
  40. if(str[i][j] == '*') {
  41. node[cnt].x = i;
  42. node[cnt].y = j;
  43. ++cnt;
  44. }
  45. }
  46. }
  47. for(int i = 0; i < n; ++i) {
  48. for(int j = 0; j < m; ++j) {
  49. bool flag = true;
  50. for(int k = 0; k < cnt; ++k) {
  51. if(node[k].x != i && node[k].y != j) {
  52. flag = false;
  53. break;
  54. }
  55. }
  56. if(flag) {
  57. f = true;
  58. ansx = i;
  59. ansy = j;
  60. break;
  61. }
  62. }
  63. if(f) {
  64. break;
  65. }
  66. }
  67. if(f) {
  68. printf("YES\n%d %d\n", ansx + 1, ansy + 1);
  69. } else {
  70. printf("NO\n");
  71. }
  72. }
  73. return 0;
  74. }

C. Vacations

题意

想要在 天内提高自己的 技能和体能,他每天进行一项活动,或者休息,如果某天体育馆是开着的,他就可以休息或者进行体育运动,如果某天有比赛,他就可以休息或者参加比赛,他在连续的两天内不会做同样的活动(运动/写代码),问他在 天内,最少休息多少天。

数据范围

题解

定义状态 ,表示从第 天到第 天,在第 天进行某项活动的情况下,他能休息的最少天数, 表示休息, 表示写代码, 表示做运动。就有下面的递推式:

过题代码

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

D. Fix a Tree

题意

给定一个长度为 的序列,其中的每个数字 ,如果只有一个数字满足条件 ,则这个数列可以表示成一棵合法的树,表示的方法是:将满足 的数字作为根,其他的数字表示 之间有一条连边。现在给出任意一个序列,更改这个数列中的一些数字,使得这个序列成为可以表示成一棵合法的树的序列,问最少需要改动的数字的个数,并输出改动后的序列。

数据范围

题解

任意 个数字 ,将 进行连边的话,一定有 条边,相当于在 个节点的图上有 条边,而 个节点的树只有 条边,所以这个图在每个连通块内一定存在一个环,且最多只有一个环。题目给出的用树构造序列的方式,就是让整个图连通,且把这个环作为根的自环,因此除自环以外,所有点之间就只有 条连边。
这道题就是一个贪心,如果原序列中有某个数字满足 ,就把这个点作为根,如果没有任何数字满足 ,就任取一条环上的边,将这条边作为自环,自环对应的点为根,再将其他的连通块(如果有的话)环上的一条边指向这个根,使得整张图连通。判环用并查集。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. #define LL long
  20. const int maxn = 200000 + 100;
  21. int n, root, cnt;
  22. int fa[maxn], num[maxn];
  23. void Init() {
  24. for(int i = 1; i <= n; ++i) {
  25. fa[i] = i;
  26. }
  27. }
  28. int Find(int x) {
  29. return (x == fa[x]? x: fa[x] = Find(fa[x]));
  30. }
  31. void unit(int x, int y) {
  32. int xx = Find(x);
  33. int yy = Find(y);
  34. fa[xx] = yy;
  35. }
  36. int main() {
  37. #ifdef Dmaxiya
  38. freopen("test.txt", "r", stdin);
  39. // freopen("test1.out", "w", stdout);
  40. #endif // Dmaxiya
  41. ios::sync_with_stdio(false);
  42. while(scanf("%d", &n) != EOF) {
  43. root = cnt = 0;
  44. Init();
  45. for(int i = 1; i <= n; ++i) {
  46. scanf("%d", &num[i]);
  47. if(num[i] == i) {
  48. root = i;
  49. }
  50. if(root == 0 && Find(num[i]) == Find(i)) {
  51. root = i;
  52. }
  53. unit(num[i], i);
  54. }
  55. Init();
  56. for(int i = 1; i <= n; ++i) {
  57. if(Find(num[i]) == Find(i)) {
  58. if(num[i] != root) {
  59. ++cnt;
  60. num[i] = root;
  61. }
  62. }
  63. unit(i, num[i]);
  64. }
  65. printf("%d\n", cnt);
  66. for(int i = 1; i <= n; ++i) {
  67. if(i != 1) {
  68. printf(" ");
  69. }
  70. printf("%d", num[i]);
  71. }
  72. printf("\n");
  73. }
  74. return 0;
  75. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注