题意:根据多米诺骨牌的编号的7*8矩阵,每个点可以和相邻的点组成的骨牌对应一个编号,问能形成多少种由编号组成的图。
分析:dfs,组成的图必须有1~28所有编号。
#pragma comment(linker, "/STACK:102400000, 102400000") #include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<stack> #include<deque> #include<queue> #include<list> #define Min(a, b) ((a < b) ? a : b) #define Max(a, b) ((a < b) ? b : a) typedef long long ll; typedef unsigned long long llu; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const ll LL_INF = 0x3f3f3f3f3f3f3f3f; const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f; const int dr[] = {0, 1}; const int dc[] = {1, 0}; const int MOD = 1e9 + 7; const double pi = acos(-1.0); const double eps = 1e-8; const int MAXN = 1000 + 10; const int MAXT = 500 + 10; using namespace std; int a[10][10]; int ans[10][10]; int id[10][10];//多米诺骨牌的编号 int vis[30]; int mark[10][10];//是否访问过该点 int cnt; void init(){ int k = 0; for(int i = 0; i < 7; ++i){ for(int j = i; j < 7; ++j){ id[i][j] = id[j][i] = ++k; } } } bool judge1(int x, int y){ return x >= 0 && x <= 6 && y >= 0 && y <= 7; } bool judge2(int x){ for(int i = 0; i < 8; ++i){ if(!mark[x][i]) return true; } return false; } void dfs(int x, int y, int cur){ if(cur == 28){ ++cnt; for(int i = 0; i < 7; ++i){ for(int j = 0; j < 8; ++j){ printf("%4d", ans[i][j]); } printf("\n"); } printf("\n"); return; } if(x == 7) return; if(y == 8){ if(judge2(x)) return;//如果这一行有未访问的 dfs(x + 1, 0, cur); return; } if(mark[x][y]){ dfs(x, y + 1, cur); return; } for(int i = 0; i < 2; ++i){//向右或向下 int tx = x + dr[i]; int ty = y + dc[i]; if(judge1(tx, ty) && !mark[tx][ty] && !vis[id[a[x][y]][a[tx][ty]]]){//下标合法、未被访问过,编号未用过 ans[x][y] = ans[tx][ty] = id[a[x][y]][a[tx][ty]]; mark[x][y] = mark[tx][ty] = vis[id[a[x][y]][a[tx][ty]]] = 1; dfs(x, y + 1, cur + 1); mark[x][y] = mark[tx][ty] = vis[id[a[x][y]][a[tx][ty]]] = 0; } } } int main(){ init(); int x; int kase = 0; while(scanf("%d", &x) == 1){ if(kase) printf("\n\n\n"); cnt = 0; memset(vis, 0, sizeof vis); memset(ans, 0, sizeof ans); memset(mark, 0, sizeof mark); a[0][0] = x; for(int i = 0; i < 7; ++i){ for(int j = 0; j < 8; ++j){ if(!i && !j) continue; scanf("%d", &a[i][j]); } } printf("Layout #%d:\n\n", ++kase); for(int i = 0; i < 7; ++i){ for(int j = 0; j < 8; ++j){ printf("%4d", a[i][j]); } printf("\n"); } printf("\nMaps resulting from layout #%d are:\n\n", kase); dfs(0, 0, 0); printf("There are %d solution(s) for layout #%d.\n", cnt, kase); } return 0; }