[BZOJ1085][SCOI2005]骑士精神 搜索
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1085
大的思路是迭代加深搜索,我们加一个明显的剪枝,当棋盘中位置不对的骑士的数目加上已经走的步数大于了限制的深度,就直接结束,然后……xjb搜就行了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int dx[]={-2,-1,1,2,2,1,-1,-2}; 6 const int dy[]={1,2,2,1,-1,-2,-2,-1}; 7 int T[10][10]; 8 int g[10][10],mx; 9 bool inline cmp(){ 10 for(int i=1;i<=5;i++) 11 for(int j=1;j<=5;j++) 12 if(g[i][j]!=T[i][j]) 13 return false; 14 return true; 15 } 16 bool eva(int k){ 17 int cnt=0; 18 for(int i=1;i<=5;i++) 19 for(int j=1;j<=5;j++){ 20 cnt+=g[i][j]!=T[i][j]; 21 if(cnt+k>mx) return false; 22 } 23 return true; 24 } 25 bool dfs(int k,int x,int y){ 26 if(x==3&&y==3&&cmp()) return true; 27 if(k>mx) return false; 28 for(int i=0;i<=7;i++){ 29 int tx=x+dx[i], 30 ty=y+dy[i]; 31 if(tx>=1&&ty>=1&&tx<=5&&ty<=5){ 32 swap(g[tx][ty],g[x][y]); 33 if(eva(k-1)&&dfs(k+1,tx,ty)) return true; 34 swap(g[tx][ty],g[x][y]); 35 } 36 } 37 return false; 38 } 39 int main(){ 40 int Test; 41 scanf("%d",&Test); 42 for(int i=3;i<=5;i++) 43 for(int j=1;j<=i;j++) 44 T[i][j]=0; 45 for(int i=1;i<=3;i++) 46 for(int j=5;j>=i;j--) 47 T[i][j]=1; 48 T[2][1]=0; 49 T[4][5]=1; 50 T[3][3]=-1; 51 while(Test--){ 52 char s[15]; 53 int sx,sy; 54 for(int i=1;i<=5;i++){ 55 scanf("%s",s+1); 56 for(int j=1;j<=5;j++){ 57 if(s[j]=='0') g[i][j]=0; 58 else if(s[j]=='1') g[i][j]=1; 59 else{ 60 g[i][j]=-1; 61 sx=i; 62 sy=j; 63 } 64 } 65 } 66 bool flag=false; 67 for(int i=1;i<=15;i++){ 68 mx=i; 69 if(dfs(1,sx,sy)){ 70 flag=true; 71 printf("%d\n",i); 72 break; 73 } 74 } 75 if(!flag) printf("-1\n"); 76 } 77 return 0; 78 }