首页 > 代码库 > ZOJ 1008 Gnome Tetravex (DFS + 剪枝)
ZOJ 1008 Gnome Tetravex (DFS + 剪枝)
Gnome Tetravex
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=8
题意:有N*N个方格,每个方格分为上下左右四个部分,每个部分填数字。现在要求重排方块,使得每两个有边相连的方块对应的数字相同。
思路:就是一个简单的搜索,我想了个剪枝,将上下左右四个方向上每个数字对应的是哪几个方块记录下来,但是这个剪枝并没有起很大的作用,还是T了。后来才发现,如果有很多个方块是相同的,会重复搜索,所以需要将相同的方块一起处理,用一个sum[]值来表示该种方块的数目。
代码:
#include<map> #include<set> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<string> #include<fstream> #include<cstring> #include<ctype.h> #include<iostream> #include<algorithm> #define INF (1<<30) #define PI acos(-1.0) #define mem(a, b) memset(a, b, sizeof(a)) #define rep(i, n) for (int i = 0; i < n; i++) #define debug puts("===============") typedef long long ll; using namespace std; struct node { int x[4]; bool operator == (const node &T) const { for (int i = 0; i < 4; i++) if (x[i] != T.x[i]) return false; return true; } }e[26]; vector<int> T[4][10]; int n; bool flag = false; int a[30]; int sum[30]; void dfs(int t) { if (flag) return ; if (t == n * n) { flag = true; return ; } if (t < n) { int u = e[a[t - 1]].x[1]; for (int i = 0; i < T[3][u].size(); i++) { int v = T[3][u][i]; if (sum[v] > 0) { sum[v]--, a[t] = v; dfs(t + 1); if (flag) return ; sum[v]++; } } } else { int u = e[a[t - n]].x[2]; for (int i = 0; i < T[0][u].size(); i++) { int v = T[0][u][i]; if (sum[v] > 0) { bool ok = true; if (t % n) { if (e[a[t - 1]].x[1] != e[v].x[3]) ok = false; } if (ok) { sum[v]--, a[t] = v; dfs(t + 1); if (flag) return ; sum[v]++; } } } } return ; } int main () { int cnt = 1; while(~scanf("%d", &n), n) { if (cnt != 1) puts(""); rep(i, 10) { rep(j, 4) { T[j][i].clear(); } } int x; memset(sum, 0, sizeof(sum)); rep(i, n * n) { rep(j, 4) { scanf("%d", &x); e[i].x[j] = x; T[j][x].push_back(i); } int k; for (k = 0; k < i; k++) if (e[k] == e[i]) { sum[k]++; break; } if (k == i) { sum[k]++; } } flag = false; for (int i = 0; i < n * n; i++) if (sum[i]) { sum[i]--; a[0] = i; dfs(1); if (flag) break; sum[i]++; } printf("Game %d: ", cnt); if (!flag) puts("Impossible"); else puts("Possible"); cnt++; } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。