ZOJ 1008.Gnome Tetravex

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1008

AC代码(C++):

#include 
#include 
#include 
#include 
#include 
#include 

#define INF 0x3f3f3f3f
#define eps 1e-8

using namespace std;

struct NODE {
	int top, right, bottom, left;
	int cnt;
};

int n, nn;
NODE node[30];
int map[10][10];
bool flag;

void dfs(int x, int y) {
	if (x == n + 1)flag = true;
	if (flag)return;
	bool flag0;
	int tmpx = x;
	int tmpy = y + 1;
	if (tmpy == n + 1) {
		tmpx++;
		tmpy = 1;
	}
	for (int i = 0; i < nn; i++) {
		if (node[i].cnt == 0)continue;
		flag0 = true;
		if (x != 1 && node[map[x - 1][y]].bottom != node[i].top)flag0 = false;
		if (y != 1 && node[map[x][y - 1]].right != node[i].left)flag0 = false;
		if (flag0) {
			node[i].cnt--;
			map[x][y] = i;
			dfs(tmpx, tmpy);
			node[i].cnt++;
		}
	}
}

int main() {
	int t = 0;
	while (cin >> n) {
		if (n == 0)break;
		t++;
		if (t != 1)cout << endl;
		int tmptop, tmpright, tmpbottom, tmpleft;
		nn = n*n;
		for(int i = 0; i < nn; i++) {
			cin >> tmptop >> tmpright >> tmpbottom >> tmpleft;
			bool flag0 = false;
			for (int j = 0; j < i; j++) {
				if (node[j].top == tmptop&&node[j].right == tmpright&&node[j].bottom == tmpbottom&&node[j].left == tmpleft) {
					node[j].cnt++;
					flag0 = true;
					i--;
					nn--;
					break;
				}
			}
			if (!flag0) {
				node[i].top = tmptop;
				node[i].right = tmpright;
				node[i].bottom = tmpbottom;
				node[i].left = tmpleft;
				node[i].cnt = 1;
			}
		}
		flag = false;
		dfs(1,1);
		cout << "Game " << t << ": ";
		if (flag)cout << "Possible\n";
		else cout << "Impossible\n";
	}

	//system("pause");
}
总结: 深搜. 本以为很简单不需要怎么剪枝, 毕竟10秒, 结果一开始还是超时了. 看了解题报告才知道这题测试用例会有很多重复的格子, 改用每种格子计数而不是vis数组就AC了.

你可能感兴趣的:(zoj)