DFS 题目,剪枝比较重要,这里使用的是把重复的方块只记录一次,用 num[] 保存它的数目。
# include# include # define N 25 + 2bool finished;int n, m, t[N][4], num[N], ans[N];void dfs(int cnt){ if (cnt == n*n) {finished = true; return ;} int x = cnt/n + 1, y = cnt%n + 1; int left = cnt, top = cnt+1-n; for (int i = 0; i < m; ++i) if (num[i]) { bool ok = true; if (x!=1 && t[i][0] != t[ans[top]][2]) ok = false; if(ok && y!=1 && t[i][3] != t[ans[left]][1]) ok = false; if (ok) { --num[i]; ans[cnt+1] = i; dfs(cnt+1); if(finished) return ; ++num[i]; } }}void init(void){ bool rpt; int top, rig, bot, lef; m = 0; memset(num, 0, sizeof(num)); for (int i = 0; i < n*n; ++i) { rpt = false; scanf("%d%d%d%d", &top, &rig, &bot, &lef); for (int j = 0; j < m; ++j) { if (t[j][0] == top && t[j][1] == rig && t[j][2] == bot && t[j][3] == lef) { rpt = true; ++num[j]; break; } } if (rpt) continue; t[m][0] = top, t[m][1] = rig, t[m][2] = bot, t[m][3] = lef; ++num[m]; ++m; }}void solve(void){ finished = false; dfs(0); if (finished) puts("Possible"); else puts("Impossible");}int main(){ int i = 0; while (~scanf("%d", &n)) { if (!n) break; init(); if(i != 0) putchar('\n'); printf("Game %d: ", ++i); solve(); } return 0;}
/**/