UVA1493 - Draw a Mess(并查集)
UVA1493 - Draw a Mess(并查集)
题目大意:一个N * M 的矩阵,每次你在上面将某个范围上色,不论上面有什么颜色都会被最新的颜色覆盖,颜色是1-9,初始的颜色是0.最后输出这个矩形中。每一个颜色有多少个。某个范围这个分为了四种,圆,矩形,菱形,还有正三角形(倒着的)。注意这题的边界,不能超出这个矩形,非常easy越界。
解题思路:由于题的矩阵范围是200 * 50000,然后操作又是50000,这样三个相乘,即使给60s也是不够的。由于行的数目比較少。假设每次都能将这一行哪个没处理过直接拿出来。而不用一个一个推断就快非常多了,这样一来就相当于每一个格子仅仅要遍历一次。所以这里就每行用一个并查集。标记这这个位置以及后面的位置能够上色的起始位置。
然后颜色更新问题仅仅要将操作反着过来上色就能够处理了。
代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int M = 50005;
const int N = 205;
int f[N][M];
int G[N][M];
int color[10];
int n, m, q;
char str[N];
struct OP {
char type;
int x, y, l, r, c;
}op[M];
int getParent (int x, int y) {
return y == f[x][y] ?
y : f[x][y] = getParent (x, f[x][y]);
}
void init() {
for (int i = q - 1; i >= 0; i--) {
scanf ("%s", str);
if (str[0] == 'D')
scanf ("%d%d%d%d", &op[i].x, &op[i].y, &op[i].l, &op[i].c);
else if (str[0] == 'T')
scanf ("%d%d%d%d", &op[i].x, &op[i].y, &op[i].l, &op[i].c);
else if (str[0] == 'R')
scanf ("%d%d%d%d%d", &op[i].x, &op[i].y, &op[i].l, &op[i].r, &op[i].c);
else
scanf ("%d%d%d%d", &op[i].x, &op[i].y, &op[i].l, &op[i].c);
op[i].type = str[0];
}
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
f[i][j] = j;
memset (color, 0, sizeof (color));
}
void circle (int x, int y, int r, int c) {
int L, R, s;
for (int i = -r; i <= r; i++) {
s = sqrt(r * r - i * i);
if (i + x >= n || i + x < 0)
continue;
L = max(y - s, 0);
L = max (getParent (i + x, L), L);
R = min (s + y, m - 1);
for (int j = L; j <= R; j++) {
if (j == getParent (i + x, j)) {
color[c]++;
f[i + x][j] = R + 1;
} else
j = getParent(i + x, j) - 1;
}
}
}
void diamond (int x, int y, int r, int c) {
int L, R;
for (int i = -r; i <= r; i++) {
if (i + x >= n || i + x < 0)
continue;
R = min (r - abs(i) + y, m - 1);
L = max (abs(i) - r + y, 0);
L = max (L, getParent (i + x, L));
for (int j = L; j <= R; j++) {
if (j == getParent (i + x, j)) {
color[c]++;
f[i + x][j] = R + 1;
} else
j = getParent (i + x, j) - 1;
}
}
}
void rectangle (int x, int y, int l, int w, int c) {
int L, R;
for (int i = x; i < min(x + l, n); i++) {
L = max (y, getParent (i, y));
R = min (y + w - 1, m - 1);
for (int j = L; j <= R; j++) {
if (j == getParent (i, j)) {
color[c]++;
f[i][j] = R + 1;
} else
j = getParent (i, j) - 1;
}
}
}
void triangle (int x, int y, int w, int c) {
int L, R, h;
h = (w + 1) / 2;
for (int i = 0; i < h; i++) {
if (i + x >= n)
break;
L = max (y - h + i + 1, 0);
L = max (getParent(i + x, L), L);
R = min (y + h - i - 1, m - 1);
for (int j = L; j <= R; j++) {
if (j == getParent (i + x, j)) {
color[c]++;
f[i + x][j] = R + 1;
} else
j = getParent (i + x, j) - 1;
}
}
}
void solve () {
for (int i = 0; i < q; i++) {
if (op[i].type == 'D')
diamond (op[i].x, op[i].y, op[i].l, op[i].c);
else if (op[i].type == 'C')
circle (op[i].x , op[i].y, op[i].l, op[i].c);
else if (op[i].type == 'T')
triangle (op[i].x, op[i].y, op[i].l, op[i].c);
else
rectangle (op[i].x, op[i].y, op[i].l, op[i].r, op[i].c);
}
}
int main () {
char str[N];
while (scanf ("%d%d%d", &n, &m, &q) != EOF) {
init ();
solve();
for (int i = 1; i < 9; i++)
printf ("%d ", color[i]);
printf ("%d\n", color[9]);
}
return 0;
}
UVA1493 - Draw a Mess(并查集)的更多相关文章
- uva 1493 - Draw a Mess(并查集)
题目链接:uva 1493 - Draw a Mess 题目大意:给定一个矩形范围,有四种上色方式,后面上色回将前面的颜色覆盖,最后问9种颜色各占多少的区域. 解题思路:用并查集维护每一个位置相应下一 ...
- Draw a Mess (并查集)
It's graduated season, every students should leave something on the wall, so....they draw a lot of g ...
- UVA 1493 Draw a Mess(并查集+set)
这题我一直觉得使用了set这个大杀器就可以很快的过了,但是网上居然有更好的解法,orz... 题意:给你一个最大200行50000列的墙,初始化上面没有颜色,接着在上面可能涂四种类型的形状(填充): ...
- 并查集(涂色问题) HDOJ 4056 Draw a Mess
题目传送门 题意:给出一个200 * 50000的像素点矩阵,执行50000次操作,每次把一个矩形/圆形/菱形/三角形内的像素点涂成指定颜色,问最后每种颜色的数量. 分析:乍一看,很像用线段树成段更新 ...
- 【HDOJ】4056 Draw a Mess
这题用线段树就MLE.思路是逆向思维,然后每染色一段就利用并查集将该段移除,均摊复杂度为O(n*m). /* 4056 */ #include <iostream> #include &l ...
- POJ 2912 - Rochambeau - [暴力枚举+带权并查集]
题目链接:http://poj.org/problem?id=2912 Time Limit: 5000MS Memory Limit: 65536K Description N children a ...
- CodeForces Roads not only in Berland(并查集)
H - Roads not only in Berland Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d ...
- POJ2912 Rochambeau [扩展域并查集]
题目传送门 Rochambeau Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4463 Accepted: 1545 ...
- POJ2912:Rochambeau(带权并查集)
Rochambeau Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5208 Accepted: 1778 题目链接:h ...
随机推荐
- caffe Python API 之Accuracy
net.acc = caffe.layers.Accuracy(net.fc3,net.label) 输出: layer { name: "acc" type: "Acc ...
- MySQL三种备份
一)备份分类 1 2 3 4 5 6 7 8 9 10 11 12 冷备:cold backup数据必须下线后备份 温备:warm backup全局施加共享锁,只能读,不能写 热备:hot backu ...
- 网络管理 SNMP基础知识
SNMP Agent快速开发 网友:SmileWolf 发布于: 2007.08.02 16:06 (共有条评论) 查看评论 | 我要评论 摘自 http:/ ...
- 深度学习方法(七):最新SqueezeNet 模型详解,CNN模型参数降低50倍,压缩461倍!
欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术感兴趣的同学加入. 继续前面关于深度学习CNN经典模型的 ...
- vim进阶-自己设置vim编辑器
我这是最基础的一些vim设置,参考文章http://blog.csdn.net/huiguixian/article/details/6394095 看大牛设置的vim,感觉很花里胡哨,以后慢慢接触: ...
- c++ primer 11 泛型算法
使用泛型算法必须包含头文件#inlucde <algorithm> 标准库还定义一组泛化的算术算法,其命名习惯与泛型算法相同,包含头文件#include <numeric> f ...
- 前端JS框架系列之requireJS基础学习
1 背景 伴随着项目功能的不断扩充,客户体验的不断完善,实现交互逻辑的JS代码变得越来越多.起初,为了管理JS代码,我们把JS从页面中解放出来独立成文件,接着又把相似的交互代码提取到公共的JS页面中. ...
- VMware虚拟机VMware Authorization Service不能启动问题
出现VMware Authorization Service不能启动问题,注意要在安装VMware Player时使用管理员权限
- Java经典设计模式之七大结构型模式
转载: Java经典设计模式之七大结构型模式 博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以 ...
- OOD沉思录 --- 面向动作与面向对象 --- 避免泛滥成灾的类
3.7 从设计中取出不需要的类 只有Get/Set方法的类不算是一个必要的类,Get/Set方法也不算是有意义的行为.这种类降级为属性更加合适. 3.8 去除系统外部的类 如果一个类只调用系统领域的方 ...