今天这道题还是关于暴力求解的。
题目
传送门:https://vjudge.net/problem/UVA-12113
这道题的意思斯这样的,你有一张总共有4X4个小方格的板,然后你手上总共有六张2X2的纸片,你要算出是否有可能用这六张纸片拼出题目中要求的样子(不一定要六张全部用上)。
乍一看这道题似乎非常麻烦,但是我们基本可以确定这只可能是一道暴力枚举考虑剪枝的题。首先我们分析下纸片可能摆放在哪些位置,我们可以惊讶的发现纸片最多仅仅只有9个位置。
那这道题的方法应该已经很简单了,我们可以使用回溯法枚举所有的情况,所有纸片可能摆放的位置,然后dfs的最大深度也只有6层(最多只有六张纸片),所以我们确定肯定不会超时。
还有一个细节问题,这题的输入比较奇怪,所以当枚举的时候要特别小心细节,哪些格子是’_’,哪些是’|’,哪些是’ ‘,都是需要注意的。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <iostream> using namespace std;
char s[5][10],a[5][10]; int state;
bool sol(int d){ int flag=1; for(int i=0;i<5;i++){ for(int j=0;j<9;j++){ if(s[i][j]!=a[i][j]) { flag = 0; break; } } if(!flag) break; } if(flag) return true; if(d>=6) return false; char copy[5][10]; for(int i=0;i<5;i++) for(int j=0;j<9;j++) copy[i][j]=a[i][j]; for(int i=0;i<9;i++){ if(!((state>>i)&1)) { state |= (1 << i); int x=i/3+1,y=2*(i%3)+1; a[x-1][y]=a[x-1][y+2]=a[x+1][y]=a[x+1][y+2]='_'; a[x][y-1]=a[x][y+3]=a[x+1][y-1]=a[x+1][y+3]='|'; a[x][y]=a[x][y+1]=a[x][y+2]=a[x+1][y+1]=' '; if(sol(d+1)) return true; state-=(1<<i); for(int r=0;r<5;r++) for(int c=0;c<9;c++) a[r][c]=copy[r][c]; } } return false; }
int main(){ for(int cas=1;gets(s[0])&&s[0][0]!='0';cas++){ cout << "Case " << cas << ": "; for(int i=1;i<5;i++) gets(s[i]); for(int i=0;i<5;i++) for(int j=0;j<9;j++) a[i][j]=' '; state=0; if(sol(0)) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }
|