输入输出格式
输入格式:
第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。
输出格式:
对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
输入输出样例
说明
题解:
看到题目,n=m=25----第一反应:爆搜
毫无优化的爆搜写法-当前空白格往可以跳的个方向去跳,在跳的过程中判断--(因为马跳到空白格相当与空白格与马的位置互换-等于空白格跳到马的位置).
考虑带一点点的优化-最优性剪枝:记录当前已经跳过的步数,如果已经超过记录的最优答案,返回-(显然这种方法对答案毫无贡献)
再往深一点考虑-还学过什么优化-----迭代加深。
发现还是卡不过去----于是就加上了A*-
这里先介绍A*--对于当前的局面,计算一个最优方案可以到达最终结果的方式(可能达不到),如果当前的步数加上预计最好的步数还完不成的话,返回。
对于每个题目,估价函数会不同,针对这个题目-最优的方案肯定是空白格每一次都可以使一匹马回到正确的位置,(当然可能不能实现-这里只是对未来的估价-并不等价与未来的真正结果)
所以-我们记录当前的当前的状态与目标状态对比,如果一个不同就cnt++(这里的cnt就是对未来的最优估价)
接下来!!!!!!!!!!!!! 上代码
1 #include<bits/stdc++.h> 2 #define R register 3 4 using namespace std; 5 6 inline long long read(){ 7 long long w=1,s=0; 8 char ch=getchar(); 9 while(ch<'0'||ch>'9') {if (ch=='-') w=-1;ch=getchar();} 10 while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); 11 return s*w; 12 } 13 14 int ans[6][6]={ 15 {0,0,0,0,0,0}, 16 {0,2,2,2,2,2}, 17 {0,1,2,2,2,2}, 18 {0,1,1,0,2,2}, 19 {0,1,1,1,1,2}, 20 {0,1,1,1,1,1} 21 }; 22 23 int num[10][10],dep,flag=0,n,m; 24 char ch[10][10]; 25 int dx[9]={0,1,1,-1,-1,2,2,-2,-2}; 26 int dy[9]={0,2,-2,2,-2,1,-1,1,-1}; 27 28 int evaluate(){ 29 int tmp=0; 30 for(int i=1;i<=5;i++) 31 for(int j=1;j<=5;j++) tmp+=(num[i][j]==ans[i][j])?0:1; 32 return tmp; 33 } 34 35 void dfs(int x,int y,int deep){ 36 if (deep==dep){if (!evaluate()) flag=1;return ;} 37 for(int i=1;i<=8;i++){ 38 int tox=x+dx[i],toy=y+dy[i]; 39 if (tox>=1&&tox<=n&&toy>=1&&toy<=m){ 40 swap(num[x][y],num[tox][toy]); 41 if (deep+evaluate()<=dep) dfs(tox,toy,deep+1); 42 swap(num[x][y],num[tox][toy]); 43 } 44 } 45 } 46 47 int main(){ 48 // freopen("a.in","r",stdin); 49 int T=read(),x,y; 50 n=5;m=5; 51 while(T--){ 52 flag=0; 53 for(int i=1;i<=n;i++) 54 for(int j=1;j<=m;j++) 55 cin>>ch[i][j]; 56 for(int i=1;i<=n;i++) 57 for(int j=1;j<=m;j++){ 58 if (ch[i][j]!='*') num[i][j]=ch[i][j]-'0'+1; 59 else x=i,y=j,num[i][j]=0; 60 } 61 if (!evaluate()){ cout<<0<<endl; continue;} 62 for(dep=1;dep<=15;dep++){ 63 dfs(x,y,0); 64 if (flag) {cout<<dep<<endl;break;} 65 } 66 if (!flag) cout<<"-1"<<endl; 67 } 68 return 0; 69 }