poj1021棋盘同构有关问题

poj1021棋盘同构问题

算模拟题吧,先把两个图的所有连通分量计算出来,然后再一一配对,有一个配对不成功便返回false,配对的过程中可旋转90,180,270,360度以及上下翻折,左右翻折。

(开始没考虑翻折,导致wa了一次,调试时才发现,然后就一次AC了,数据太弱,骗分都可以过。。。)

包括调试代码总共200+行代码。第一次刷题写这么读代码阿。。汗~

AC代码(由于数据很弱故没优化,时间有点长。。。。。。囧):

忘了还有中心对称旋转。。。


# include <stdlib.h>
# include <string.h>
# include <stdio.h>
# define paste(x,y) x ## y
# define DEBU

int cs1[110][110];
int cs2[110][110];
int x[110][110];
int y[110][110];
int xx[] = {1,-1,0,0};
int yy[] = {0,0,-1,1};
int w,h,n,max;

int cmp() {
	for (int i = 0; i < max; ++ i) {
		for (int j = 0; j < max; ++ j) {
			if (x[i][j] != y[i][j]) {
				return 0;
			}
		}
	}
	return 1;
}

int toBound(int c) {
	int t[110][110];
	if (c == 1) {
		memcpy(t, x, sizeof(t));
	}
	else {
		memcpy(t, y, sizeof(t));
	}
	int up;
	int left;
#ifdef DEBUG
	for (int i = 0; i < max; ++ i) {
		for (int j = 0; j < max; ++ j) {
			printf ("%d ", x[i][j]);
		}
		printf("\n");
	}
	printf ("\n*************\n");
#endif
	for (up = 0; up < max; ++ up) {
		for (int i = 0; i < max; ++ i) {
			if (t[up][i]) goto flag1;
		}
	}
flag1:
	for (left = 0;left < max ; ++ left) {
		for (int i = 0; i < max; ++ i) {
			if (t[i][left]) goto flag2;
		}
	}
flag2:
	if(left)
	for (int i = left; i < max; ++ i) {
		for (int j = 0; j < max; ++ j) {
			t[j][i - left] = t[j][i];
			t[j][i] = 0;
		}
	}
	if(up)
	for (int i = up; i < 110; ++ i) {
		for (int j = 0; j < 110; ++ j) {
			t[i - up][j] = t[i][j];
			t[i][j] = 0;
		}
	}
	if (c == 1) {
		memcpy(x, t, sizeof(t));
	}
	else {
		memcpy(y, t, sizeof(t));
	}
#ifdef DEBUG
	for (int i = 0; i < max; ++ i) {
		for (int j = 0; j < max; ++ j) {
			printf ("%d ", x[i][j]);
		}
		printf("\n");
	}
	printf ("\n*************\n");
#endif
	return 0;
}

int up_down(){
	int t[110][110];
	memset(t, 0, sizeof(t));
	for (int i = 0; i < max; ++ i) {
		for (int j = 0; j < max; ++ j) {
			t[i][j] = x[max - 1 - i][j];
		}
	}
	memcpy(x, t, sizeof(t));
	toBound(1);
	return 0;
}

int left_right(){
	int t[110][110];
	memset(t, 0, sizeof(t));
	for (int i = 0; i < max; ++ i) {
		for (int j = 0; j < max; ++ j) {
			t[i][j] = x[i][max - 1 - j];
		}
	}
	memcpy(x, t, sizeof(t));
	toBound(1);
	return 0;
}

int rotal(){
	int t[110][110];
	memset(t, 0, sizeof(t));
	for (int i = 0; i < max; ++ i) {
		for (int j = 0; j < max; ++ j) {
			t[i][j] = x[w - 1 - j][i];
		}
	}
	memcpy(x, t, sizeof(x));
	toBound(1);
	return 0;
}

int dfs1(int x, int y, int color) {
	int xi, yi;
	cs1[x][y] = color;
	for (int i = 0; i < 4; ++ i) {
		xi = x + xx[i];
		yi = y + yy[i];
		if (xi >= 0 && xi < w && yi >= 0 && yi < h) {
			if (cs1[xi][yi] == 1) {
				cs1[xi][yi] = color;
				dfs1(xi, yi, color);
			}
		}
	}
	return 0;
}

int dfs2(int x, int y, int color) {
	int xi, yi;
	cs2[x][y] = color;
	for (int i = 0; i < 4; ++ i) {
		xi = x + xx[i];
		yi = y + yy[i];
		if (xi >= 0 && xi < w && yi >= 0 && yi < h) {
			if (cs2[xi][yi] == 1) {
				cs2[xi][yi] = color;
				dfs2(xi, yi, color);
			}
		}
	}
	return 0;
}

int check() {
	int c1 = 1, c2 = 1;
	for (int i = 0; i < w; ++ i) {
		for (int j = 0; j < h; ++ j) {
			if (cs1[i][j] == 1) {
				++ c1;
				dfs1(i, j, c1);
			}
			if (cs2[i][j] == 1) {
				++ c2;
				dfs2(i, j, c2);
			}
		}
	}
#ifdef DEBU
	for (int i = 0; i < max; ++ i ){
		for (int j = 0; j < max; ++ j) {
			printf ("%d ", cs1[i][j]);
		}
		printf ("\n");
	}
	printf ("\n");
	for (int i = 0; i < max; ++ i) {
		for (int j = 0; j < max; ++ j) {
			printf ("%d ", cs2[i][j]);
		}
		printf ("\n");
	}
#endif
	if(c1 != c2) return 0;
	for (int i = 2; i <= c1; ++ i) {
		int flag = 0;
		for (int j = 2; j <= c2; ++ j) {
			memset (x, 0, sizeof(x));
			memset (y, 0, sizeof(y));
			for (int m = 0; m < w; ++ m) {
				for (int n = 0; n < h; ++ n) {
					if (cs1[m][n] == i) {
						x[m][n] = 1;
					}
					if (cs2[m][n] == j) {
						y[m][n] = 1;
					}
				}
			}

			toBound(2);
			for (int i = 0; i < 4; ++ i) {
				rotal();
				if (cmp()) {
					flag = 1;
					break;
				}
				left_right();
				if (cmp()) {
					flag = 1;
					break;
				}
				left_right();
				up_down();
				if (cmp()) {
					flag = 1;
					break;
				}
				up_down();
				left_right();
				up_down();
				if (cmp()) {
					flag = 1;
					break;
				}
				up_down();
				left_right();

			}
			for (int i = 0; i < 4; ++ i) {
				rotal();left_right();
				if (cmp()) {
					flag = 1;
					break;
				}
			}
			for (int i = 0; i < 4; ++ i) {
				rotal();up_down();
				if (cmp()) {
					flag = 1;
					break;
				}
			}
			for (int i = 0; i < 4; ++ i) {
				rotal();up_down();left_right();
				if (cmp()) {
					flag = 1;
					break;
				}
			}

		}
		if (!flag) {
#ifdef DEBU
			printf ("faile at %d\n", i);
			for (int i = 0; i < max; ++ i) {
				for (int j = 0; j < max; ++ j) {
					printf ("%d ", x[i][j]);
				}
				printf ("\n");
			}
			printf ("\n");
			for (int i = 0; i < max; ++ i) {
				for (int j = 0; j < max; ++ j) {
					printf ("%d ", y[i][j]);
				}
				printf ("\n");
			}
#endif
			return 0;
		}
	}

	return 1;
}


int main () {
	int ts;
	for (scanf("%d", &ts); ts; -- ts){
		scanf("%d %d %d", &w, &h, &n);
		max = w > h ? w : h;
		memset (cs1, 0, sizeof(cs1));
		memset (cs2, 0, sizeof(cs2));
		for (int i = 0; i < n; ++ i) {
			int x, y;
			scanf("%d %d", &x, &y);
			++ cs1[x][y];
		}
		for (int i = 0; i < n; ++ i) {
			int x, y;
			scanf("%d %d", &x, &y);
			++ cs2[x][y];
		}
		if (check()) {
			printf ("YES\n");
		}
		else {
			printf ("NO\n");
		}
	}

	return 0;
}