[SCOI2005]骑士精神
题目描述
输入输出格式
输入格式:第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。
输出格式:对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
输入输出样例
说明
迭代次数dep
A*算法是利用估价函数h()进行剪枝
h()大于实际值就会错误
h()小于实际值太多效率会底下
所以h要慎重考虑
此题h可以这么计算:
当前棋盘有cnt个与目标棋盘不同的棋子
如果cnt等于0,那么退出
如果cnt不等于0,那么说明至少要走cnt-1步
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 char ch[10][10]; 8 int s[5][5]; 9 const int ss[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 int sx,sy,deeeep,flag; 16 const int dx[8]={2,-2,1,-1,2,-2,1,-1},dy[8]={1,1,2,2,-1,-1,-2,-2}; 17 int h() 18 {int i,j; 19 int cnt=0; 20 for (i=0;i<=4;i++) 21 { 22 for (j=0;j<=4;j++) 23 { 24 if (s[i][j]!=ss[i][j]) cnt++; 25 } 26 } 27 return cnt; 28 } 29 void dfs(int x,int y,int sum,int dep) 30 {int i; 31 if (flag) return; 32 int H=h(); 33 if (!H) 34 { 35 flag=1; 36 return; 37 } 38 if (sum+H-1>dep) return; 39 int xx,yy; 40 for (i=0;i<8;i++) 41 { 42 xx=x+dx[i],yy=y+dy[i]; 43 if (xx<0||yy<0||xx>=5||yy>=5) continue; 44 swap(s[x][y],s[xx][yy]); 45 dfs(xx,yy,sum+1,dep); 46 swap(s[x][y],s[xx][yy]); 47 } 48 } 49 int main() 50 {int T,i,j; 51 cin>>T; 52 while (T--) 53 { 54 for (i=0;i<=4;i++) 55 { 56 scanf("%s",ch[i]); 57 for (j=0;j<=4;j++) 58 if (ch[i][j]=='*') sx=i,sy=j,s[i][j]=2; 59 else s[i][j]=ch[i][j]-'0'; 60 } 61 deeeep=0; 62 flag=0; 63 while (deeeep<=15) 64 { 65 dfs(sx,sy,0,deeeep); 66 if (flag) break; 67 deeeep++; 68 } 69 if (flag==0) printf("-1\n"); 70 else printf("%d\n",deeeep); 71 } 72 }