UVa 211 - The Domino Effect [DFS剪枝]
这道题只看书上的中文解释可能有些费力,理解题后还是比较简单的,对每个数字看能否与右边或下边的数字配对组成一张牌,注意加各种剪枝就行。
#include <bits/stdc++.h> using namespace std; int kase, solution; int tab[10][10], res[10][10], vis[30]; int dict[7][7]; const int dir[2][2] = { { 0, 1 }, { 1, 0 } }; void init() { ++kase; solution = 0; memset(tab, 0, sizeof(tab)); memset(res, 0, sizeof(res)); memset(vis, 0, sizeof(vis)); int cnt = 0; for (int i = 0; i <= 6; ++i) for (int j = i; j <= 6; ++j) dict[i][j] = ++cnt; } bool in() { for (int i = 1; i <= 7; ++i) for (int j = 1; j <= 8; ++j) if(!(cin >> tab[i][j])) return false; if(kase>=2) printf("\n\n\n"); printf("Layout #%d:\n\n", kase); for (int i = 1; i <= 7; ++i){ for (int j = 1; j <= 8; ++j) printf("%4d", tab[i][j]); printf("\n"); } printf("\n"); return true; } void out() { if(!solution) printf("Maps resulting from layout #%d are:\n", kase); ++solution; printf("\n"); for (int i = 1; i <= 7; ++i){ for (int j = 1; j <= 8; ++j) printf("%4d", res[i][j]); printf("\n"); } } inline int calc(int x, int y) { if (x > y) swap(x, y); return dict[x][y]; } void DFS(int d, int r0, int c0) { if (d == 28) {out(); return;} if (c0==9) c0 = 1, ++r0; if (res[r0][c0]){ DFS(d, r0, c0 + 1); return; } for (int i = 0; i < 2; ++i){ int r = r0 + dir[i][0], c = c0 + dir[i][1]; if(r > 7 || c > 8 || res[r][c]) continue; int val = calc(tab[r0][c0], tab[r][c]); if (!vis[val]){ vis[val] = 1; res[r][c] = res[r0][c0] = val; DFS(d + 1, r0, c0 + 1); vis[val] = 0; res[r][c] = res[r0][c0] = 0; } } } int main() { ios::sync_with_stdio(false); while (true){ init(); if(!in()) return 0; DFS(0, 1, 1); printf("\nThere are %d solution(s) for layout #%d.\n", solution, kase); } return 0; }