bzoj1085: [SCOI2005]骑士精神
1085: [SCOI2005]骑士精神
Time Limit: 10 Sec Memory Limit: 162 MBDescription
在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑
士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空
位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步
数完成任务。
Input
第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑
士,*表示空位。两组数据之间没有空行。
Output
对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
Sample Input
2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100
Sample Output
7
-1
-1
HINT
Source
A*
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 7 const int xx[8]={1,2,1,2,-1,-2,-1,-2}; 8 const int yy[8]={2,1,-2,-1,2,1,-2,-1}; 9 const int ans[5][5]={ 10 {1,1,1,1,1}, 11 {0,1,1,1,1}, 12 {0,0,2,1,1}, 13 {0,0,0,0,1}, 14 {0,0,0,0,0} 15 }; 16 int t,n,m,a[5][5],res,flag; 17 char s[10]; 18 19 bool A_A(int h,int g){ 20 int res=0; 21 for(int i=0;i<=4;i++) 22 for(int j=0;j<=4;j++) 23 if(a[i][j]!=ans[i][j]) res++; 24 if(res+h>g) return 0;else return 1; 25 } 26 27 bool judge(){ 28 for(int i=0;i<=4;i++) 29 for(int j=0;j<=4;j++) 30 if(a[i][j]!=ans[i][j]) return 0; 31 return 1; 32 } 33 34 void dfs(int step,int k,int x,int y){ 35 if(step==k){ 36 if(judge()) flag=1; 37 return; 38 } 39 for(int i=0;i<=7;i++){ 40 int nowx=x+xx[i],nowy=y+yy[i]; 41 if(nowx<0||nowx>4||nowy<0||nowy>4) continue; 42 swap(a[nowx][nowy],a[x][y]); 43 if(A_A(step,k)) dfs(step+1,k,nowx,nowy); 44 swap(a[nowx][nowy],a[x][y]); 45 } 46 } 47 48 int main(){ 49 scanf("%d",&t); 50 while(t--){ 51 int x,y; 52 for(int i=0;i<=4;i++){ 53 scanf("%s",s); 54 int len=strlen(s); 55 for(int j=0;j<len;j++){ 56 if(s[j]=='*'){ 57 a[i][j]=2; 58 x=i,y=j; 59 } 60 else a[i][j]=s[j]-'0'; 61 } 62 } 63 flag=0; 64 for(int k=0;k<=15;k++){ 65 dfs(0,k,x,y); 66 if(flag){printf("%d\n",k); break;} 67 } 68 if(!flag) printf("-1\n"); 69 } 70 }