• AOJ 0531 坐标离散化


    一、题目大意

    在(0<=x<=w,0<=y<=h)的坐标系里有多个矩形,把区域分成了多个部分,我们需要针对找出被矩形分割的连通的区块数量。

    二、解题思路

    这个题目其实和学DFS时候那个找出连通的水洼是一样的。只是这个地图比较大,没办法建立那么大的数组,但是矩形的数量也很少,所以考虑使用坐标离散化。

    坐标离散化的思路其实也很简单,就是我们把每一个有效坐标k和它 的前一个k-1和后一个坐标k+1都放在一个数组里,然后对这个数组排序加去重(先排序再双指针去重最快),之后用元素k在这个数组里的位置来替换这个元素本身的值,这种离散化对于需要打表的题,比如DP、DFS、BFS比较有效。

    本题目给出的是坐标,但是DFS需要用的是区块,所以我就把(x1,y1)到(x2,y2)的矩形看作从[x1,x2-1]到[y1,y2-1]这些坐标中间的区块。那么[0,w-1]的坐标范围,其实真正的放置区块的数量就是[0,w-2]也就是w-1个区块,这个说的其实不清晰,我表达能力确实是太差了。主要的意思就是解释下为什么我把去重后的数量-1作为w和h,因为坐标和区块之间差一个,所以减少一个。

    三、代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. typedef pair<int, int> P;
    6. int x[6007], y[6007], xLen, yLen, w, h, x_1[1007], x_2[1007], y_1[1007], y_2[1007], n, ans;
    7. int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
    8. bool field[6007][6007];
    9. queue

      que;

    10. void input()
    11. {
    12. ans = 0;
    13. scanf("%d", &n);
    14. for (int i = 0; i < n; i++)
    15. {
    16. scanf("%d%d%d%d", &x_1[i], &y_1[i], &x_2[i], &y_2[i]);
    17. }
    18. }
    19. void compress()
    20. {
    21. xLen = 0;
    22. for (int i = 0; i < n; i++)
    23. {
    24. if (x_1[i] > 0)
    25. {
    26. x[xLen++] = x_1[i] - 1;
    27. }
    28. x[xLen++] = x_1[i];
    29. if (x_1[i] < w)
    30. {
    31. x[xLen++] = x_1[i] + 1;
    32. }
    33. if (x_2[i] > 0)
    34. {
    35. x[xLen++] = x_2[i] - 1;
    36. }
    37. x[xLen++] = x_2[i];
    38. if (x_2[i] < w)
    39. {
    40. x[xLen++] = x_2[i] + 1;
    41. }
    42. }
    43. yLen = 0;
    44. for (int i = 0; i < n; i++)
    45. {
    46. if (y_1[i] > 0)
    47. {
    48. y[yLen++] = y_1[i] - 1;
    49. }
    50. y[yLen++] = y_1[i];
    51. if (y_1[i] < h)
    52. {
    53. y[yLen++] = y_1[i] + 1;
    54. }
    55. if (y_2[i] > 0)
    56. {
    57. y[yLen++] = y_2[i] - 1;
    58. }
    59. y[yLen++] = y_2[i];
    60. if (y_2[i] < h)
    61. {
    62. y[yLen++] = y_2[i] + 1;
    63. }
    64. }
    65. sort(x, x + xLen);
    66. sort(y, y + yLen);
    67. }
    68. void distinctBy2Posinter()
    69. {
    70. int tmpLen = 1;
    71. for (int i = 1; i < xLen; i++)
    72. {
    73. if (x[tmpLen - 1] != x[i])
    74. {
    75. x[tmpLen++] = x[i];
    76. }
    77. }
    78. xLen = tmpLen;
    79. tmpLen = 1;
    80. for (int i = 1; i < yLen; i++)
    81. {
    82. if (y[tmpLen - 1] != y[i])
    83. {
    84. y[tmpLen++] = y[i];
    85. }
    86. }
    87. yLen = tmpLen;
    88. }
    89. void handleX_1X_2Y_1Y_2()
    90. {
    91. for (int i = 0; i < n; i++)
    92. {
    93. x_1[i] = lower_bound(x, x + xLen, x_1[i]) - x;
    94. x_2[i] = lower_bound(x, x + xLen, x_2[i]) - x;
    95. y_1[i] = lower_bound(y, y + yLen, y_1[i]) - y;
    96. y_2[i] = lower_bound(y, y + yLen, y_2[i]) - y;
    97. }
    98. w = xLen - 1;
    99. h = yLen - 1;
    100. }
    101. void handleField()
    102. {
    103. for (int i = 0; i < h; i++)
    104. {
    105. for (int j = 0; j < w; j++)
    106. {
    107. field[i][j] = true;
    108. }
    109. }
    110. for (int i = 0; i < n; i++)
    111. {
    112. for (int j = y_1[i]; j <= (y_2[i] - 1); j++)
    113. {
    114. for (int k = x_1[i]; k <= (x_2[i] - 1); k++)
    115. {
    116. field[j][k] = false;
    117. }
    118. }
    119. }
    120. }
    121. void bfs()
    122. {
    123. while (!que.empty())
    124. {
    125. P p = que.front();
    126. que.pop();
    127. for (int i = 0; i < 4; i++)
    128. {
    129. int ny = p.first + dy[i];
    130. int nx = p.second + dx[i];
    131. if (ny >= 0 && ny < h && nx >= 0 && nx < w && field[ny][nx])
    132. {
    133. field[ny][nx] = false;
    134. que.push(P(ny, nx));
    135. }
    136. }
    137. }
    138. }
    139. void solve()
    140. {
    141. for (int i = 0; i < h; i++)
    142. {
    143. for (int j = 0; j < w; j++)
    144. {
    145. if (field[i][j])
    146. {
    147. field[i][j] = false;
    148. que.push(P(i, j));
    149. bfs();
    150. ans++;
    151. }
    152. }
    153. }
    154. }
    155. int main()
    156. {
    157. while (true)
    158. {
    159. scanf("%d%d", &w, &h);
    160. if (w == 0 && h == 0)
    161. {
    162. break;
    163. }
    164. input();
    165. compress();
    166. distinctBy2Posinter();
    167. handleX_1X_2Y_1Y_2();
    168. handleField();
    169. solve();
    170. printf("%d\n", ans);
    171. }
    172. return 0;
    173. }

  • 相关阅读:
    MySQL内置函数
    kubernetes 之 minikube折腾记
    【论文简述】 Point-MVSNet:Point-Based Multi-View Stereo Network(ICCV 2019)
    使用Vue3在浏览器端进行zip文件压缩
    hexdump 命令 -e 选项
    口袋参谋:99.99%商家都学的防骗技巧!
    JDK19新特性使用详解
    虚拟机开启网络代理设置
    ESP32_HTTP请求获取天气,含json解析
    牛客刷题之图论-最小生成树
  • 原文地址:https://blog.csdn.net/qq_53038151/article/details/133216678