https://vjudge.net/problem/UVA-211
题目
给你28张“双六”多米诺骨牌,编号如下:
Bone # Pips Bone # Pips Bone # Pips Bone # Pips 1 0 | 0 8 1 | 1 15 2 | 3 22 3 | 6 2 0 | 1 9 1 | 2 16 2 | 4 23 4 | 4 3 0 | 2 10 1 | 3 17 2 | 5 24 4 | 5 4 0 | 3 11 1 | 4 18 2 | 6 25 4 | 6 5 0 | 4 12 1 | 5 19 3 | 3 26 5 | 5 6 0 | 5 13 1 | 6 20 3 | 4 27 5 | 6 7 0 | 6 14 2 | 2 21 3 | 5 28 6 | 6
在7*8的网格中每张牌各摆一张,如图所示,左边是各个格子的点数,右边是各个格子所属的骨牌编号。
7 x 8 grid of pips map of bone numbers 6 6 2 6 5 2 4 1 28 28 14 7 17 17 11 11 1 3 2 0 1 0 3 4 10 10 14 7 2 2 21 23 1 3 2 4 6 6 5 4 8 4 16 25 25 13 21 23 1 0 4 3 2 1 1 2 8 4 16 15 15 13 9 9 5 1 3 6 0 4 5 5 12 12 22 22 5 5 26 26 5 5 4 0 2 6 0 3 27 24 24 3 3 18 1 19 6 0 5 3 4 2 0 3 27 6 6 20 20 18 1 19
输入左图,你的任务是输出所有可能的右图
题解
整理数据= =将每张牌的每个数字与另外一边的数字对应起来,可以加快搜索速度
只有28层,不用担心爆栈
太激动了……又是花一大堆时间写的一道题!(4小时)
(早睡早起.jpg)
AC代码
#include<bits/stdc++.h> using namespace std; #define REP(r,x,y) for(register int r=(x); r<(y); r++) #define REPE(r,x,y) for(register int r=(x); r<=(y); r++) #define MAXN 7 #define MAXM 8 #ifdef sahdsg #define DBG(...) printf(__VA_ARGS__) #else #define DBG(...) #endif int mp[MAXN][MAXM]; int ans[MAXN][MAXM]; bool vis[29]; int ansc=0; int bones[][2] = { {-1,-1},{0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{2,2},{2,3},{2,4},{2,5},{2,6},{3,3},{3,4},{3,5},{3,6},{4,4},{4,5},{4,6},{5,5},{5,6},{6,6} }; int sq[][7]= { {1*2,2*2+1,3*2+1,4*2+1,5*2+1,6*2+1,7*2+1}, {2*2,8*2,9*2+1,10*2+1,11*2+1,12*2+1,13*2+1}, {3*2,9*2,14*2,15*2+1,16*2+1,17*2+1,18*2+1}, {4*2,10*2,15*2,19*2,20*2+1,21*2+1,22*2+1}, {5*2,11*2,16*2,20*2,23*2,24*2+1,25*2+1}, {6*2,12*2,17*2,21*2,24*2,26*2,27*2+1}, {7*2,13*2,18*2,22*2,25*2,27*2,28*2} }; inline bool getblock() { ansc=0; memset(ans,-1,sizeof ans); REP(i,0,7) REP(j,0,8) { if(scanf("%d", &mp[i][j])==-1) return false; } return true; } //int back; bool dfs(int d, int x, int y) { // DBG("#%d %d %d ", d, x, y); st: if(y>=8) y=0, x++; if(d>=28) { ansc++; REP(i,0,MAXN) { REP(j,0,MAXM) { if(j) putchar(' '); printf("%d", ans[i][j]); } putchar(' '); } putchar(' '); return true; } if(ans[x][y]!=-1) { y++; goto st; } int k=mp[x][y]; bool f=false; REP(i,0,8) { int t=sq[k][i]; int p=t&1; t>>=1; if(vis[t]) continue; // assert(t>0); if(x+1<7) if(mp[x+1][y]==bones[t][p] && ans[x+1][y]==-1) { f=true;vis[t]=true; ans[x][y]=t, ans[x+1][y]=t; dfs(d+1, x,y+1); ans[x][y]=-1, ans[x+1][y]=-1; vis[t]=false; } if(y+1<8) if(mp[x][y+1]==bones[t][p] && ans[x][y+1]==-1) { f=true;vis[t]=true; ans[x][y]=t, ans[x][y+1]=t; dfs(d+1, x,y+2); ans[x][y]=-1, ans[x][y+1]=-1; vis[t]=false; } } return f; } int main() { #ifdef sahdsg freopen("in.txt", "r", stdin); #endif int kase=0; while(getblock()) { if(kase) puts(" "); kase++; printf("Layout #%d: ", kase); REP(i,0,7) { REP(j,0,8) { if(j) putchar(' '); printf("%d", mp[i][j]); } putchar(' '); } putchar(' '); printf("Maps resulting from layout #%d are: ", kase); dfs(0,0,0); printf("There are %d solution(s) for layout #%d. ", ansc, kase); } return 0; }