UVA1493 - Draw a Mess(并查集)

题目链接

题目大意:一个N * M 的矩阵,每次你在上面将某个范围上色,不论上面有什么颜色都会被最新的颜色覆盖,颜色是1-9,初始的颜色是0.最后输出这个矩形中。每一个颜色有多少个。某个范围这个分为了四种,圆,矩形,菱形,还有正三角形(倒着的)。注意这题的边界,不能超出这个矩形,非常easy越界。

解题思路:由于题的矩阵范围是200 * 50000,然后操作又是50000,这样三个相乘,即使给60s也是不够的。由于行的数目比較少。假设每次都能将这一行哪个没处理过直接拿出来。而不用一个一个推断就快非常多了,这样一来就相当于每一个格子仅仅要遍历一次。所以这里就每行用一个并查集。标记这这个位置以及后面的位置能够上色的起始位置。

然后颜色更新问题仅仅要将操作反着过来上色就能够处理了。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <cstdlib>
  5. #include <algorithm>
  6. using namespace std;
  7. const int M = 50005;
  8. const int N = 205;
  9. int f[N][M];
  10. int G[N][M];
  11. int color[10];
  12. int n, m, q;
  13. char str[N];
  14. struct OP {
  15. char type;
  16. int x, y, l, r, c;
  17. }op[M];
  18. int getParent (int x, int y) {
  19. return y == f[x][y] ?
  20. y : f[x][y] = getParent (x, f[x][y]);
  21. }
  22. void init() {
  23. for (int i = q - 1; i >= 0; i--) {
  24. scanf ("%s", str);
  25. if (str[0] == 'D')
  26. scanf ("%d%d%d%d", &op[i].x, &op[i].y, &op[i].l, &op[i].c);
  27. else if (str[0] == 'T')
  28. scanf ("%d%d%d%d", &op[i].x, &op[i].y, &op[i].l, &op[i].c);
  29. else if (str[0] == 'R')
  30. scanf ("%d%d%d%d%d", &op[i].x, &op[i].y, &op[i].l, &op[i].r, &op[i].c);
  31. else
  32. scanf ("%d%d%d%d", &op[i].x, &op[i].y, &op[i].l, &op[i].c);
  33. op[i].type = str[0];
  34. }
  35. for (int i = 0; i <= n; i++)
  36. for (int j = 0; j <= m; j++)
  37. f[i][j] = j;
  38. memset (color, 0, sizeof (color));
  39. }
  40. void circle (int x, int y, int r, int c) {
  41. int L, R, s;
  42. for (int i = -r; i <= r; i++) {
  43. s = sqrt(r * r - i * i);
  44. if (i + x >= n || i + x < 0)
  45. continue;
  46. L = max(y - s, 0);
  47. L = max (getParent (i + x, L), L);
  48. R = min (s + y, m - 1);
  49. for (int j = L; j <= R; j++) {
  50. if (j == getParent (i + x, j)) {
  51. color[c]++;
  52. f[i + x][j] = R + 1;
  53. } else
  54. j = getParent(i + x, j) - 1;
  55. }
  56. }
  57. }
  58. void diamond (int x, int y, int r, int c) {
  59. int L, R;
  60. for (int i = -r; i <= r; i++) {
  61. if (i + x >= n || i + x < 0)
  62. continue;
  63. R = min (r - abs(i) + y, m - 1);
  64. L = max (abs(i) - r + y, 0);
  65. L = max (L, getParent (i + x, L));
  66. for (int j = L; j <= R; j++) {
  67. if (j == getParent (i + x, j)) {
  68. color[c]++;
  69. f[i + x][j] = R + 1;
  70. } else
  71. j = getParent (i + x, j) - 1;
  72. }
  73. }
  74. }
  75. void rectangle (int x, int y, int l, int w, int c) {
  76. int L, R;
  77. for (int i = x; i < min(x + l, n); i++) {
  78. L = max (y, getParent (i, y));
  79. R = min (y + w - 1, m - 1);
  80. for (int j = L; j <= R; j++) {
  81. if (j == getParent (i, j)) {
  82. color[c]++;
  83. f[i][j] = R + 1;
  84. } else
  85. j = getParent (i, j) - 1;
  86. }
  87. }
  88. }
  89. void triangle (int x, int y, int w, int c) {
  90. int L, R, h;
  91. h = (w + 1) / 2;
  92. for (int i = 0; i < h; i++) {
  93. if (i + x >= n)
  94. break;
  95. L = max (y - h + i + 1, 0);
  96. L = max (getParent(i + x, L), L);
  97. R = min (y + h - i - 1, m - 1);
  98. for (int j = L; j <= R; j++) {
  99. if (j == getParent (i + x, j)) {
  100. color[c]++;
  101. f[i + x][j] = R + 1;
  102. } else
  103. j = getParent (i + x, j) - 1;
  104. }
  105. }
  106. }
  107. void solve () {
  108. for (int i = 0; i < q; i++) {
  109. if (op[i].type == 'D')
  110. diamond (op[i].x, op[i].y, op[i].l, op[i].c);
  111. else if (op[i].type == 'C')
  112. circle (op[i].x , op[i].y, op[i].l, op[i].c);
  113. else if (op[i].type == 'T')
  114. triangle (op[i].x, op[i].y, op[i].l, op[i].c);
  115. else
  116. rectangle (op[i].x, op[i].y, op[i].l, op[i].r, op[i].c);
  117. }
  118. }
  119. int main () {
  120. char str[N];
  121. while (scanf ("%d%d%d", &n, &m, &q) != EOF) {
  122. init ();
  123. solve();
  124. for (int i = 1; i < 9; i++)
  125. printf ("%d ", color[i]);
  126. printf ("%d\n", color[9]);
  127. }
  128. return 0;
  129. }

UVA1493 - Draw a Mess(并查集)的更多相关文章

  1. uva 1493 - Draw a Mess(并查集)

    题目链接:uva 1493 - Draw a Mess 题目大意:给定一个矩形范围,有四种上色方式,后面上色回将前面的颜色覆盖,最后问9种颜色各占多少的区域. 解题思路:用并查集维护每一个位置相应下一 ...

  2. Draw a Mess (并查集)

    It's graduated season, every students should leave something on the wall, so....they draw a lot of g ...

  3. UVA 1493 Draw a Mess(并查集+set)

    这题我一直觉得使用了set这个大杀器就可以很快的过了,但是网上居然有更好的解法,orz... 题意:给你一个最大200行50000列的墙,初始化上面没有颜色,接着在上面可能涂四种类型的形状(填充):  ...

  4. 并查集(涂色问题) HDOJ 4056 Draw a Mess

    题目传送门 题意:给出一个200 * 50000的像素点矩阵,执行50000次操作,每次把一个矩形/圆形/菱形/三角形内的像素点涂成指定颜色,问最后每种颜色的数量. 分析:乍一看,很像用线段树成段更新 ...

  5. 【HDOJ】4056 Draw a Mess

    这题用线段树就MLE.思路是逆向思维,然后每染色一段就利用并查集将该段移除,均摊复杂度为O(n*m). /* 4056 */ #include <iostream> #include &l ...

  6. POJ 2912 - Rochambeau - [暴力枚举+带权并查集]

    题目链接:http://poj.org/problem?id=2912 Time Limit: 5000MS Memory Limit: 65536K Description N children a ...

  7. CodeForces Roads not only in Berland(并查集)

    H - Roads not only in Berland Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d ...

  8. POJ2912 Rochambeau [扩展域并查集]

    题目传送门 Rochambeau Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4463   Accepted: 1545 ...

  9. POJ2912:Rochambeau(带权并查集)

    Rochambeau Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5208   Accepted: 1778 题目链接:h ...

随机推荐

  1. Builder设计模式--改善构造器多个参数时可显著改善可读性

    作为一名程序开发者,设计模式其实一直有在接触,只是没有专门的去学过,所以可能对设计模式没有一个系统的理解.在一次项目中,需要使用到第三方服务商提供的功能,为了尽快的熟悉其功能代码,在官网下了demo来 ...

  2. NVIDIA DIGITS 学习笔记(NVIDIA DIGITS-2.0 + Ubuntu 14.04 + CUDA 7.0 + cuDNN 7.0 + Caffe 0.13.0)

    转自:http://blog.csdn.net/enjoyyl/article/details/47397505?from=timeline&isappinstalled=0#10006-we ...

  3. 小技巧:tar命令打包目录时,排除文件和目录的命令

    今天不巧要用上,百度. tar zcvf fd.tar.gz pardir --exclude=pardir/file1 --exclude=pardir/dir1

  4. JavaScript(获取或设置html元素的宽,高,坐标),确定和判断鼠标是否在元素内部,二级导航菜单鼠标离开样式问题解决

    设置: document.getElementById('id').style.width=value    document.getElementById('id').style.height=va ...

  5. EOJ 3256 拼音魔法

    模拟. 有$a$先标$a$,其次是$o$和$e$,$o$和$e$在韵母中不会同时存在.最后是$u$和$i$,这两个字母在韵母中可能同时存在,标在后面的那个.输出那些字符的话直接输出就可以了. 举几个例 ...

  6. 洛谷P2296 寻找道路 [拓扑排序,最短路]

    题目传送门 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点 ...

  7. Android中xml tool属性

    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0309/2567.html 我是搬运工.. 总结而言tool属性就是为了在IDE ...

  8. ajax个人总结

    ajax是什么? AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法. ...

  9. 关于maven工程的几个BUG

    换了个新的环境,重新导入的maven工程出现了2个BUG: 1.Could not calculate build plan: Plugin org.apache.maven.plugins:mave ...

  10. Prime Number CodeForces - 359C (属于是数论)

    Simon has a prime number x and an array of non-negative integers a1, a2, ..., an. Simon loves fracti ...