HDU 2514 Another Eight Puzzle
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2514
对8个位置填数,有连线的两个位置不能填连续的数.
搜索时加上限定条件即可.除了搜索,记得还有一种更优雅的解法.
#include <iostream> using namespace std; int judge[8][8] = {{3,1,2,3},{4,0,2,4,5},{6,0,1,3,4,5,6},{4,0,2,5,6},{4,1,2,5,7},{6,1,2,3,4,6,7},{4,2,3,5,7},{3,4,5,6}}; //judge[i][0] = 第i列相连点的数量,judge[i][j](j>0) = 相连点.图的数组结构 int num = 0; //记录解的数量 bool vis[9]; // vis记录8个数中被用过的数 int a[8],fil[8],seq[8];; // fil记录有多少个待填点 int n; void dfs(int t) { if(num > 1) return; if(t == n) { num ++ ; for(int i=0;i < 8;i++) { seq[i] = a[i]; } return; } for(int i = 1;i <= 8;i++) //枚举8个数 { if(!vis[i]) { for(int j=1;j < judge[fil[t]][0];j++) //枚举相连点 { if(abs(a[judge[fil[t]][j]] - i) == 1 && a[judge[fil[t]][j]] != 0) //若连续则跳过 { break; } } if(j < judge[fil[t]][0]) continue; //若非正常退出,则出现连续break跳出则不满足条件 //否则,进行深搜 vis[i] = 1; a[fil[t]] = i; dfs(t+1); if(num > 1) return; vis[i] = 0; a[fil[t]] = 0; } } } int main(int argc, const char *argv[]) { int T; // freopen("input.txt","r",stdin); cin>>T; for(int k = 1;k <= T;k++) { n = 0; memset(vis,0,sizeof(vis)); for(int i=0;i < 8;i++) { cin>>a[i]; if(a[i]) vis[a[i]] = 1; else if(!a[i]) //若为0.fil记录位置 { fil[n++] = i; } } num = 0; dfs(0); cout<<"Case "<<k<<":"<<" "; if(num == 1) { cout<<seq[0]; for(int i=1;i < 8;i++) { cout<<" "<<seq[i]; } cout<<endl; } else if(num > 1) cout<<"Not unique"<<endl; else cout<<"No answer"<<endl; } return 0; }