[关闭]
@Dmaxiya 2020-12-12T15:21:10.000000Z 字数 3701 阅读 1050

Codeforces Round #453 (Div. 2)

Codeforces


Contests 链接:Codeforces Round #453 (Div. 2)
过题数:3
排名:408/8956

A. Visiting a Friend

题意

的家在 处,他的朋友家在 处,他将要拜访这位朋友,在路上有 个传送点,每个传送点的位置是 ,每个传送点都有一个最远能够传送到的最右边的位置 ,它可以将 传送到 之间的任意一点,问 是否可以只通过传送点就到达他的朋友家。

输入

第一行为两个整数 ,接下去 行每行两个整数 ,对于每一个 ,都满足

输出

如果 可以只通过传送点就到达他的朋友家,输出 ,否则输出 ,大小写任意。

样例

输入 输出 提示
3 5
0 2
2 4
3 5
YES 如图:

rVc301.png

可以从 到达 ,然后通过第二个传送点到达 ,再通过第三个传送点到达
3 7
0 4
2 5
6 7
NO 如图:

rVctfO.png

无法从 通过传送点到达他的朋友家。

题解

按照题意模拟,从 开始,尽量往远处跑,最后能够跑到的点只要大于等于 ,就输出

过题代码

  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 <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. int n, m, a, b, ans;
  19. int main() {
  20. #ifdef Dmaxiya
  21. freopen("test.txt", "r", stdin);
  22. #endif // Dmaxiya
  23. ios::sync_with_stdio(false);
  24. while(scanf("%d%d", &n, &m) != EOF) {
  25. ans = 0;
  26. for(int i = 0; i < n; ++i) {
  27. scanf("%d%d", &a, &b);
  28. if(ans >= a) {
  29. ans = max(ans, b);
  30. }
  31. }
  32. if(ans >= m) {
  33. printf("YES\n");
  34. } else {
  35. printf("NO\n");
  36. }
  37. }
  38. return 0;
  39. }

B. Coloring a Tree

题意

对于一棵 个节点的有根树,给这棵树上的每个节点都涂上一种颜色,每次涂色可以选择一个节点,并将这个节点的子树(包括这个节点自身)全都涂上这种颜色,每个节点初始的颜色都是 ,要按照给定的涂色方式将这棵树涂上颜色,问最少需要涂多少次颜色。

输入

第一行为一个整数 ,第二行为 个整数 ,第 个整数 代表第 个节点的父节点,第三行为 个整数 ,表示每个节点要涂上的颜色。

输出

输出最少需要涂色的次数。

样例

输入 输出 提示
6
1 2 2 1 5
2 1 1 1 1 1
3 给定的树如图:



首先选择树根并将整棵树涂成颜色 ,如图:



接着可以选择节点 并将 的子树都涂成颜色



最后选择节点 并将对应的子树都涂成颜色

7
1 1 2 3 1 4
3 3 1 1 1 2 3
5

题解

贪心地从根节点开始涂色,按照 的顺序先涂根节点,再涂它的子树,只有出现子节点颜色和父节点颜色不同的时候才需要涂色,因此只要统计子节点颜色和父节点颜色不同的个数就是答案。

过题代码

  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 <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 10000 + 100;
  19. int n, ans;
  20. int color[maxn], fa[maxn];
  21. int main() {
  22. #ifdef Dmaxiya
  23. freopen("test.txt", "r", stdin);
  24. #endif // Dmaxiya
  25. ios::sync_with_stdio(false);
  26. while(scanf("%d", &n) != EOF) {
  27. ans = 0;
  28. for(int i = 2; i <= n; ++i) {
  29. scanf("%d", &fa[i]);
  30. }
  31. for(int i = 1; i <= n; ++i) {
  32. scanf("%d", &color[i]);
  33. if(color[i] != color[fa[i]]) {
  34. ++ans;
  35. }
  36. }
  37. printf("%d\n", ans);
  38. }
  39. return 0;
  40. }

C. Hashing Trees

题意

给定一个长度为 的序列 ,第 个数字 表示一棵树上第 层的节点数为 ,判断是否存在不同构的满足条件的两棵树。

输入

第一行为一个整数 ,第二行为 个整数 ,数据保证至少有一种满足条件的树的结构,且

输出

如果只有唯一一种满足条件的树的结构,则输出 ,否则在第一行输出 ,接下来两行每行 个数字,第 个数字表示第 个节点的父节点,如果这个节点为根节点,则它的父节点为

样例

输入 输出 提示
2
1 1 1
perfect 给定的序列只有唯一一种满足条件的树的结构:

rVcd6H.jpg
2
1 2 2
ambiguous
0 1 1 3 3
0 1 1 3 2
给定的序列有两种满足条件的结构:

rVcr7t.jpg

题解

序列中只要存在两个连续的大于等于 的数字,就存在两种不同构的树满足条件,第一棵数每一层都以上一层的第一个节点为父节点,第二棵树只要在连续的两个 中第二个 对应的那一层,拿出一个节点作为上一层第二个节点的子节点,两棵树就不是同构的了。

过题代码

  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 <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 200000 + 100;
  19. int h, cnt;
  20. int num[maxn];
  21. int main() {
  22. #ifdef Dmaxiya
  23. freopen("test.txt", "r", stdin);
  24. #endif // Dmaxiya
  25. ios::sync_with_stdio(false);
  26. while(scanf("%d", &h) != EOF) {
  27. int Index = -1;
  28. cnt = 1;
  29. for(int i = 0; i <= h; ++i) {
  30. scanf("%d", &num[i]);
  31. }
  32. for(int i = 0; i < h; ++i) {
  33. if(num[i] >= 2 && num[i + 1] >= 2) {
  34. Index = i + 1;
  35. break;
  36. }
  37. }
  38. if(Index == -1) {
  39. printf("perfect\n");
  40. continue;
  41. }
  42. printf("ambiguous\n");
  43. int root = 0;
  44. int first = 0;
  45. for(int i = 0; i <= h; ++i) {
  46. root = first;
  47. first = cnt;
  48. for(int j = 0; j < num[i]; ++j) {
  49. if(i != 0) {
  50. printf(" ");
  51. }
  52. printf("%d", root);
  53. ++cnt;
  54. }
  55. }
  56. printf("\n");
  57. cnt = 1;
  58. first = 0;
  59. for(int i = 0; i <= h; ++i) {
  60. root = first;
  61. first = cnt;
  62. for(int j = 0; j < num[i]; ++j) {
  63. if(i != 0) {
  64. printf(" ");
  65. }
  66. if(Index == i && j == 1) {
  67. printf("%d", root + 1);
  68. } else {
  69. printf("%d", root);
  70. }
  71. ++cnt;
  72. }
  73. }
  74. printf("\n");
  75. }
  76. return 0;
  77. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注