[关闭]
@Dmaxiya 2026-04-27T07:36:47.000000Z 字数 7627 阅读 2

AIM Tech Round 5 (Div. 1 + Div. 2)

Codeforces


Contests 链接:AIM Tech Round 5 (Div. 1 + Div. 2)
过题数:3
排名:750/8224

A. Find Square

题意

在一个 的网格中,最初每个格子的颜色都是白色的,其中有一个长和宽都为奇数的长方形,长方形区域内的所有格子都是黑色的,问这个长方形的中心的坐标。

输入

第一行为两个整数 ,接下去 行每行一个长度为 的字符串,字符串只包含 WB 两种字符,W 表示白色方格,B 表示黑色方格。

输出

输出长方形的中心格坐标。

样例

输入
5 6
WWBBBW
WWBBBW
WWBBBW
WWWWWW
WWWWWW
输出
2 4
输入
3 3
WWW
BWW
WWW
输出
2 1

题解

每遇到一个 B 字符,都取横坐标与纵坐标的 ,就能得到左上角与右下角的坐标,取中点,就是答案。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <climits>
  6. #include <cmath>
  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 <functional>
  16. #include <algorithm>
  17. using namespace std;
  18. #define LL long long
  19. const int maxn = 200 + 100;
  20. int n, m, maxx, maxy, minx, miny;
  21. char str[maxn][maxn];
  22. int main() {
  23. #ifdef Dmaxiya
  24. freopen("test.txt", "r", stdin);
  25. // freopen("out.txt", "w", stdout);
  26. #endif // Dmaxiya
  27. ios::sync_with_stdio(false);
  28. while(scanf("%d%d", &n, &m) != EOF) {
  29. minx = miny = INT_MAX;
  30. maxx = maxy = -1;
  31. for(int i = 1; i <= n; ++i) {
  32. scanf("%s", str[i] + 1);
  33. for(int j = 1; j <= m; ++j) {
  34. if(str[i][j] == 'B') {
  35. minx = min(minx, i);
  36. miny = min(miny, j);
  37. maxx = max(maxx, i);
  38. maxy = max(maxy, j);
  39. }
  40. }
  41. }
  42. printf("%d %d\n", (maxx + minx) / 2, (maxy + miny) / 2);
  43. }
  44. return 0;
  45. }

B. Unnatural Conditions

题意

定义函数 为数字 的每个十进制位相加的和,给定两个整数 ,构造两个整数 ,使得:

输入

输入包含两个整数

输出

输出两行,每行一个整数,分别表示整数 ,要求两个整数的长度都不超过 ,两个整数都不能有前导零。

样例

输入
6 5
输出
6
7
提示
输入
8 16
输出
35
53

题解

由于 ,因此由 加一个 与由 组成的数字相加,一定能得到 ,因此只要令 ,就能满足所有的

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <climits>
  6. #include <cmath>
  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 <functional>
  16. #include <algorithm>
  17. using namespace std;
  18. #define LL long long
  19. int n, m;
  20. int main() {
  21. #ifdef Dmaxiya
  22. freopen("test.txt", "r", stdin);
  23. // freopen("out.txt", "w", stdout);
  24. #endif // Dmaxiya
  25. ios::sync_with_stdio(false);
  26. while(scanf("%d%d", &n, &m) != EOF) {
  27. for(int i = 0; i < 1128; ++i) {
  28. printf("8");
  29. }
  30. printf("9\n");
  31. for(int i = 0; i < 1129; ++i) {
  32. printf("1");
  33. }
  34. printf("\n");
  35. }
  36. return 0;
  37. }

C. Rectangles

题意

给定 个矩形,其中一定有一个点,存在于至少 个矩形的内部或者边上,求这个点的坐标。

输入

第一行为一个整数 ,接下去 行每行四个整数 ,表示每个矩形的左下角与右上角坐标。

输出

输出两个整数 ,表示存在于至少 个矩形内的点的坐标。

样例

输入
3
0 0 1 1
1 1 2 2
3 0 4 1
输出
1 1
输入
3
0 0 1 1
0 1 1 2
1 0 2 1
输出
1 1
提示
第一、二组数据所示矩形如图,其中被高亮的点是可能的答案:

输入
4
0 0 5 5
0 0 4 4
1 1 4 4
1 1 4 4
输出
1 1
输入
5
0 0 10 8
1 2 6 7
2 3 5 6
3 4 4 5
8 1 9 2
输出
3 4
提示
第三、四组数据所示矩形如图:

题解

把数组随机排列几次,每次都取矩形的交,每当与某个矩形取交集为空集的时候,就跳过这个矩形,并计数 ,如果计数值小于等于 ,则最后得到的矩形交一定是 个矩形的交。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <climits>
  6. #include <cmath>
  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 <functional>
  16. #include <algorithm>
  17. #include <ctime>
  18. using namespace std;
  19. #define LL long long
  20. const int maxn = 200000 + 100;
  21. struct Node {
  22. int x1, y1, x2, y2;
  23. bool judge() {
  24. return x1 <= x2 && y1 <= y2;
  25. }
  26. };
  27. Node operator^(const Node &a, const Node &b) {
  28. Node tmp;
  29. tmp.x1 = max(a.x1, b.x1);
  30. tmp.y1 = max(a.y1, b.y1);
  31. tmp.x2 = min(a.x2, b.x2);
  32. tmp.y2 = min(a.y2, b.y2);
  33. return tmp;
  34. }
  35. int n;
  36. Node ans;
  37. Node node[maxn];
  38. void Rand() {
  39. for(int i = 0; i < n; ++i) {
  40. swap(node[i], node[rand() % n]);
  41. }
  42. }
  43. int main() {
  44. #ifdef Dmaxiya
  45. freopen("test.txt", "r", stdin);
  46. // freopen("out.txt", "w", stdout);
  47. #endif // Dmaxiya
  48. ios::sync_with_stdio(false);
  49. srand((unsigned)time(NULL));
  50. while(scanf("%d", &n) != EOF) {
  51. for(int i = 0; i < n; ++i) {
  52. scanf("%d%d%d%d", &node[i].x1, &node[i].y1, &node[i].x2, &node[i].y2);
  53. }
  54. while(true) {
  55. int cnt = 0;
  56. Node tmp = node[0];
  57. Node ttmp;
  58. for(int i = 1; i < n; ++i) {
  59. ttmp = tmp ^ node[i];
  60. if(!ttmp.judge()) {
  61. ++cnt;
  62. continue;
  63. }
  64. tmp = ttmp;
  65. }
  66. if(cnt <= 1) {
  67. ans = tmp;
  68. break;
  69. }
  70. Rand();
  71. }
  72. printf("%d %d\n", ans.x1, ans.y1);
  73. }
  74. return 0;
  75. }

D. Array Restoration

题意

有一个长度为 的序列,可以对这 个序列进行 次操作,第 次操作选择一个区间 ,将这个区间内的所有数字用 替换,每个位置上的数字至少被一个区间覆盖,最后将这个序列中的某几个数字改为 。现在题目给出最终的序列,问是否存在合法的 次操作,能够得到给出的序列,求 次操作后(将序列某些数字变为 之前)的序列。

输入

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

输出

如果给出的序列无法从上面的操作中得到,输出 ,否则在第一行输出 ,第二行输出 次操作之后的 个整数。

样例

输入
4 3
1 0 2 3
输出
YES
1 2 2 3
提示
替换也是合法的,但是用 替换是不合法的。
输入
3 10
10 10 10
输出
YES
10 10 10
提示
不论前 次操作是怎么样,第 次操作是选择区间 即可。
输入
5 6
6 5 6 2 2
输出
NO
提示
由于第 次操作必须在第 次操作之前,所以不可能先将区间 更新为 之后再将区间 更新为
输入
3 5
0 0 0
输出
YES
5 4 2
提示
有许多种操作对于 而言都是合法的。

题解

由于数字大的一定比数字小的后更新,所以每个数字出现的左端点与右端点之间的数字不能小于它自身,可以用线段树维护最小值,从 询问第 个数字出现的左端点 与右端点 ,如果在查询区间最小值时遇到 的情况,就向下将 更新为当前数字再进行查询。记得首先查询序列内是否有数字 ,如果没有数字 就将其中任意一个 修改为 ,如果无法修改则直接输出 。所有询问与更新结束后,如果序列中仍含有 ,就将所有 赋值为

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <climits>
  6. #include <cmath>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <functional>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 200000 + 100;
  19. int n, q;
  20. int num[maxn], L[maxn], R[maxn];
  21. int Min[maxn << 2];
  22. void push_up(int rt) {
  23. Min[rt] = min(Min[rt << 1], Min[rt << 1 | 1]);
  24. }
  25. void build(int l, int r, int rt) {
  26. if(l == r) {
  27. Min[rt] = num[l];
  28. return ;
  29. }
  30. int m = (l + r) >> 1;
  31. build(l, m, rt << 1);
  32. build(m + 1, r, rt << 1 | 1);
  33. push_up(rt);
  34. }
  35. void update(int x, int l, int r, int rt) {
  36. if(l == r) {
  37. Min[rt] = x;
  38. num[l] = x;
  39. return ;
  40. }
  41. int m = (l + r) >> 1;
  42. if(Min[rt << 1] == 0) {
  43. update(x, l, m, rt << 1);
  44. }
  45. if(Min[rt << 1 | 1] == 0) {
  46. update(x, m + 1, r, rt << 1 | 1);
  47. }
  48. push_up(rt);
  49. }
  50. int query(int L, int R, int x, int l, int r, int rt) {
  51. if(L <= l && r <= R) {
  52. if(Min[rt] == 0) {
  53. update(x, l, r, rt);
  54. }
  55. return Min[rt];
  56. }
  57. int m = (l + r) >> 1;
  58. int ret = INT_MAX;
  59. if(L <= m) {
  60. ret = min(ret, query(L, R, x, l, m, rt << 1));
  61. }
  62. if(m < R) {
  63. ret = min(ret, query(L, R, x, m + 1, r, rt << 1 | 1));
  64. }
  65. push_up(rt);
  66. return ret;
  67. }
  68. int main() {
  69. #ifdef Dmaxiya
  70. freopen("test.txt", "r", stdin);
  71. // freopen("10.out", "w", stdout);
  72. #endif // Dmaxiya
  73. while(scanf("%d%d", &n, &q) != EOF) {
  74. for(int i = 0; i <= q; ++i) {
  75. L[i] = n + 1;
  76. R[i] = 0;
  77. }
  78. for(int i = 1; i <= n; ++i) {
  79. scanf("%d", &num[i]);
  80. L[num[i]] = min(L[num[i]], i);
  81. R[num[i]] = max(R[num[i]], i);
  82. }
  83. if(L[q] > R[q]) {
  84. if(L[0] != n + 1) {
  85. num[L[0]] = q;
  86. L[q] = R[q] = L[0];
  87. } else {
  88. printf("NO\n");
  89. continue;
  90. }
  91. }
  92. build(1, n, 1);
  93. bool flag = true;
  94. for(int i = q; i >= 1; --i) {
  95. if(L[i] > R[i]) {
  96. continue;
  97. }
  98. if(query(L[i], R[i], i, 1, n, 1) < i) {
  99. flag = false;
  100. break;
  101. }
  102. }
  103. if(!flag) {
  104. printf("NO\n");
  105. continue;
  106. }
  107. printf("YES\n");
  108. for(int i = 1; i <= n; ++i) {
  109. if(i != 1) {
  110. printf(" ");
  111. }
  112. if(num[i] == 0) {
  113. printf("1");
  114. } else {
  115. printf("%d", num[i]);
  116. }
  117. }
  118. printf("\n");
  119. }
  120. return 0;
  121. }

E. Down or Right

题意

这是一道交互题,有一个 的网格,其中有一些网格是可以行走的,而有一些是无法行走的,在可以行走的网格中,下一步只能往右或下两个方向移动到下一格可以行走的网格中,但是我们并不知道这个网格哪些格子是可以行走的那些无法行走。 要从 点走到 点,每次可以询问他从 点是否能到达 点, 将会回答 或者 ,且每次询问 的哈密顿距离不能小于 ,最终输出从 的合法行走方案。询问的次数不能超过

输入

第一次输入为一个整数 ,后面的输入为 或者 ,取决于输出的询问。

输出

如果为询问,则按照 的格式询问,如果已经可以求得路径,则第一个字符为 !,空一格之后,输出 个字符,第 个字符为 D 表示第 步需要往下走,为 R 表示需要往右走。

样例

输入
4

YES

NO

YES

YES
输出

? 1 1 4 4

? 1 2 4 3

? 4 1 4 4

? 1 4 4 4

! RDRRDD
提示
网格中的可行走方格与不可行走方格如下图:

题解

如果“左上的点”表示与点 的哈密顿距离不大于 的所有点,“右下的点”表示与点 的哈密顿距离不大于 的点,则先从 开始询问左上的点是否能到达 ,能往右就尽量往右走,再从 开始询问 能否到达右下的点,能往上就尽量往上,最后这两条路径一定会重合于某一点 ,其中

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <climits>
  6. #include <cmath>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <functional>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. const int maxn = 20000 + 100;
  19. int n, cntl, cntr;
  20. char ret[10];
  21. char ansl[maxn], ansr[maxn];
  22. int dis(int x1, int y1, int x2, int y2) {
  23. return abs(x1 - x2) + abs(y1 - y2);
  24. }
  25. int main() {
  26. #ifdef Dmaxiya
  27. // freopen("test.txt", "r", stdin);
  28. // freopen("10.out", "w", stdout);
  29. #endif // Dmaxiya
  30. scanf("%d", &n);
  31. int x = 1, y = 1;
  32. while(dis(1, 1, x, y + 1) <= n - 1) {
  33. int xx = x;
  34. int yy = y + 1;
  35. printf("? %d %d %d %d\n", xx, yy, n, n);
  36. fflush(stdout);
  37. scanf("%s", ret);
  38. if(ret[0] == 'Y') {
  39. ansl[cntl++] = 'R';
  40. ++y;
  41. } else {
  42. ansl[cntl++] = 'D';
  43. ++x;
  44. }
  45. }
  46. x = y = n;
  47. while(dis(x - 1, y, n, n) <= n - 1) {
  48. int xx = x - 1;
  49. int yy = y;
  50. printf("? %d %d %d %d\n", 1, 1, xx, yy);
  51. fflush(stdout);
  52. scanf("%s", ret);
  53. if(ret[0] == 'Y') {
  54. ansr[cntr++] = 'D';
  55. --x;
  56. } else {
  57. ansr[cntr++] = 'R';
  58. --y;
  59. }
  60. }
  61. ansl[cntl] = '\0';
  62. printf("! %s", ansl);
  63. for(int i = cntr - 1; i >= 0; --i) {
  64. printf("%c", ansr[i]);
  65. }
  66. printf("\n");
  67. fflush(stdout);
  68. return 0;
  69. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注