hdu 4056 Draw a Mess(数据结构-并查集)

Draw a Mess

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 864    Accepted Submission(s): 180

Problem Description

It‘s graduated season, every students should leave something on the wall, so....they draw a lot of geometry shape with different color.

When teacher come to see what happened, without getting angry, he was surprised by the talented achievement made by students. He found the wall full of color have a post-modern style so he want to have an in-depth research on it.

To simplify the problem, we divide the wall into n*m (1 ≤ n ≤ 200, 1 ≤ m ≤ 50000) pixels, and we have got the order of coming students who drawing on the wall. We found that all students draw four kinds of geometry shapes in total that is Diamond, Circle, Rectangle
and Triangle. When a student draw a shape in pixel (i, j) with color c (1 ≤ c ≤ 9), no matter it is covered before, it will be covered by color c.

There are q (1 ≤ q ≤ 50000) students who have make a drawing one by one. And after q operation we want to know the amount of pixels covered by each color.

Input

There are multiple test cases.

In the first line of each test case contains three integers n, m, q. The next q lines each line contains a string at first indicating the geometry shape:

* Circle: given xc, yc, r, c, and you should cover the pixels(x, y) which satisfied inequality (x - xc)2 + (y - yc)2 ≤ r2 with color c;

* Diamond: given xc, yc, r, c, and you should cover the pixels(x, y) which satisfied inequality abs(x - xc) + abs(y - yc) ≤ r with color c;

* Rectangle: given xc, yc, l, w, c, and you should cover the pixels(x, y) which satisfied xc ≤ x ≤ xc+l-1, yc ≤ y ≤ yc+w-1 with color c;

* Triangle: given xc, yc, w, c, W is the bottom length and is odd, the pixel(xc, yc) is the middle of the bottom. We define this triangle is isosceles and the height of this triangle is (w+1)/2, you should cover the correspond pixels with color c;

Note: all shape should not draw out of the n*m wall! You can get more details from the sample and hint. (0 ≤ xc, x ≤ n-1, 0 ≤ yc, y ≤ m-1)

Output

For each test case you should output nine integers indicating the amount of pixels covered by each color.

Sample Input

8 8 4
Diamond 3 3 1 1
Triangle 4 4 3 2
Rectangle 1 1 2 2 3
Circle 6 6 2 4

Sample Output

4 4 4 11 0 0 0 0 0

Hint

The final distribution of different colors:
00000000
03300000
03310000
00111000
00022240
00002444
00004444
00000444

一开始用线段树做,hdu上弹MLE,然后TLE,但是zojAC。最后看了别人怎么做的,竟然用并查集,又是新技能呀!get!

思路:

乍一看,行只有200,比列少很多,所以逐行处理每个图形覆盖到该行的区间。之后的图形覆盖前面的图形,所以,我们在这里从后往前处理。

现在,我们来看看每一行是怎么处理的:

如下图,顶层模型是我从线段的右端开始涂色,当涂到已经涂过的格子时,我直接跳到下一个未涂色的格子,这样就减少了遍历涂过色格子的时间。而如何跳到我们需要的格子呢?就用到了并查集的东西了。

#include <string>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

const double eps = 1e-8;
const int maxn = 210;
const int maxm = 50010;
int m , n , q , color[15] , father[maxm] , vis[maxm];
struct Node{
	char op;
	int xc , yc , r , l , w,c;
	Node(char OP = 'x' , int XC = 0, int YC = 0, int R = 0, int L = 0 , int W = 0, int C = 0){
		op = OP , xc = XC , yc = YC , l = L , r = R , w = W , c = C;
	}
};
vector<Node> v;

int findFather(int x){
	if(father[x] != x) return father[x] = findFather(father[x]);
	return father[x];
}

inline bool getCircle(int pos,int xc,int yc,int r,int &L,int &R) {
    int tmp = r*r-(pos-xc)*(pos-xc);
    if(tmp<0) return false;
    L = int(-sqrt(tmp*1.0)+yc+1.0-eps);
    //L = max(0,L);
    if(0 > L) L = 0;
    R = int(sqrt(tmp*1.0)+yc);
    //R = min(m-1,R);
    if(R > m-1) R = m-1;
    if(L>R) return false;
    return true;
}
inline bool getRect(int pos,int xc,int yc,int l,int w,int &L,int &R) {
    if(pos<xc || pos >= xc+l) return false;
    else {
        L = yc;
        //L = max(0,L);
        if(0 > L) L = 0;
        R = yc+w-1;
        //R = min(m-1,R);
        if(R > m-1) R = m-1;
        if(L>R) return false;
        return true;
    }
}
inline bool getDiamond(int pos,int xc,int yc,int r , int &L , int &R) {
    int tmp = r - abs(xc-pos);
    if(tmp < 0) return false;
    L = yc-tmp;
    //L = max(0,L);
    if(0 > L) L = 0;
    R = yc+tmp;
    //R = min(m-1,R);
    if(R > m-1) R = m-1;
    if(L>R) return false;
    return true;
}

inline bool getTriangle(int pos , int xc , int yc , int w , int &L , int &R){
	if(pos < xc) return false;
	L = yc-w/2+pos-xc;
	R = yc+w/2-(pos-xc);
	//L = max(L , 0);
	if(0 > L) L = 0;
	//R = min(R , m-1);
	if(R > m-1) R = m-1;
	if(L>R) return false;
	return true;
}

void initial(){
	for(int i = 0; i < 15; i++) color[i] = 0;
	v.clear();
	for(int i = 0; i < maxm; i++) father[i] = i , vis[i] = 0;
}

void computing(){
	char shape[20];
	int xc , yc , w , r , c , l , L , R;
	while(q--){
		scanf("%s" , shape);
		if(shape[0] == 'C'){
			scanf("%d%d%d%d" , &xc , &yc , &r , &c);
		}
		if(shape[0] == 'D'){
			scanf("%d%d%d%d" , &xc , &yc , &r , &c);
		}
		if(shape[0] == 'R'){
			scanf("%d%d%d%d%d" ,&xc ,&yc ,&l ,&w ,&c);
		}
		if(shape[0] == 'T'){
			scanf("%d%d%d%d" ,&xc,&yc,&w,&c);
		}
		v.push_back(Node(shape[0] , xc , yc , r , l , w , c));
	}
	int fl , fr;
	for(int i = 0; i < n; i++){
			//cout << i << ": ";
		for(int j = 0; j < m; j++) father[j] = j , vis[j] = 0;
		for(int k = v.size()-1; k >= 0; k--){
			if(v[k].op == 'C' && !getCircle(i , v[k].xc , v[k].yc , v[k].r , L , R))continue;
			if(v[k].op == 'D' && !getDiamond(i , v[k].xc , v[k].yc , v[k].r , L , R)) continue;
			if(v[k].op == 'R' && !getRect(i , v[k].xc , v[k].yc , v[k].l , v[k].w , L , R)) continue;
			if(v[k].op == 'T' && !getTriangle(i , v[k].xc , v[k].yc , v[k].w , L , R)) continue;
			c = v[k].c;
			//cout << L << " " << R << " " << c << endl;
			int fl = findFather(L);
			while(R>=L){
				if(vis[R] == 0){
					vis[R] = 1;
					color[c]++;
				}
				fr = findFather(R);
				R = min(fr-1 , R-1);
				if(fr > fl)father[fr] = fl;
			}
		}
	}
	printf("%d" , color[1]);
	for(int i = 2; i <= 9; i++) printf(" %d" , color[i]);
	printf("\n");
}

int main(){
	while(~scanf("%d%d%d" , &n , &m , &q)){
		initial();
		computing();
	}
	return 0;
}
时间: 2024-12-22 12:39:02

hdu 4056 Draw a Mess(数据结构-并查集)的相关文章

HDU 1988 Cube Stacking (数据结构-并查集)

Cube Stacking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 18900   Accepted: 6568 Case Time Limit: 1000MS Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start w

HDU 3047 Zjnu Stadium 带权并查集

题目来源:HDU 3047 Zjnu Stadium 题意:给你一些人 然后每次输入a b c 表示b在距离a的右边c处 求有多少个矛盾的情况 思路:用sum[a] 代表a点距离根的距离 每次合并时如果根一样 判断sum数组是否符合情况 根不一样 合并两棵树 这里就是带权并查集的精髓 sum[y] = sum[a]-sum[b]+x 这里y的没有合并前b的根 #include <cstdio> #include <cstring> using namespace std; cons

hdu 1829 A Bug&#39;s Life 并查集系列

1 #include "cstdio" 2 #include "iostream" 3 #include "cstring" 4 #include "vector" 5 #include "queue" 6 using namespace std; 7 8 #define MAXN 2222 9 int fa[MAXN]; 10 int rnk[MAXN]; //秩 表示某点与根的距离 11 int n,

POJ 1984 Navigation Nightmare (数据结构-并查集)

Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 4072   Accepted: 1615 Case Time Limit: 1000MS Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usually numbered/labeled 1..N. A series o

HDU 3367 Pseudoforest(伪森林)(并查集)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3367 题意:在图论中,如果一个森林中有很多连通分量,并且每个连通分量中至多有一个环,那么这个森林就称为伪森林. 现在给出一个森林,求森林包含的最大的伪森林,其大小通过所有边的权值之和来比较. 分析: 1.一开始想的是:在每个连通分量中求一个最大生成树,然后加一条最大的边,再把每个连通分量算出来的值加起来,但WA了.这并不是最优的,因为还存在这种情况:一个连通分量里最初有两个环,但是伪森林要求最多一个

hdu 1272 小希的迷宫(简单并查集)

小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 31396    Accepted Submission(s): 9726 Problem Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是

POJ 2492 || HDU 1829:A Bug&#39;s Life(并查集)

传送门: POJ:点击打开链接 HDU:点击打开链接 A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 27624   Accepted: 8979 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they fe

HDU 1232:畅通问题(并查集)

畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 29362    Accepted Submission(s): 15452 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可以实现交通(但不一定有

POJ 1703 Find them, Catch them(数据结构-并查集)

Find them, Catch them Description The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, the police first needs to identify which gang a criminal b