传送门:https://www.luogu.org/problemnew/show/P2324
虽然不是第一次听说A*算法,但是第一次接触呢。。
适用范围:
1.在有一定的限制条件时使用(例如本题中“如果能在1515步以内(包括1515步)到达目标状态,则输出步数,否则输出-1−1。“)。
2.题目中说输出所以解中的任何一组解。
然后我们会有一个估价函数,大概是当前状态下离得到答案的最优解是多少吧
如果当前已走步数dep加当前状态的最优解val>最大步数maxdep就说明这种情况不行,直接回溯
然后剩下的就和爆搜差不多啦qwq
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <cmath>
using namespace std;
char flag,s[6];
int t,sx,sy,a[6][6];
int moved[8][2]={{1,2},{-1,2},{1,-2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1}};
int goal[6][6]={{0,0,0,0,0,0},{0,1,1,1,1,1},{0,0,1,1,1,1},{0,0,0,2,1,1},{0,0,0,0,0,1},{0,0,0,0,0,0}};
int read()
{
int xx=0,kk=1;char ch=' ';
while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
return kk*xx;
}
int getval()
{
int tmp=0;
for(int i=1;i<=5;++i)
for(int j=1;j<=5;++j)
if(a[i][j]!=goal[i][j]) tmp++;
return tmp;
}
bool check(int x,int y)
{
if(x<1||x>5||y<1||y>5) return 0;
return 1;
}
void A_star(int x,int y,int dep,int maxdep)
{
if(dep==maxdep){flag=getval()?false:true;return;}
for(int i=0;i<8;++i)
{
int tx=x+moved[i][0];
int ty=y+moved[i][1];
if(check(tx,ty))
{
swap(a[x][y],a[tx][ty]);
if(dep+getval()<=maxdep)
A_star(tx,ty,dep+1,maxdep);
swap(a[x][y],a[tx][ty]);
}
}
}
int main()
{
t=read();
while(t--)
{
flag=false;
for(int i=1;i<=5;++i)
{
scanf("%s",s+1);
for(int j=1;j<=5;++j)
{
if(s[j]=='*')
a[i][j]=2,sx=i,sy=j;
else a[i][j]=s[j]=='1';
}
}
for(int i=0;i<=15;++i)
{
A_star(sx,sy,0,i);
if(flag){printf("%d\n",i);break;}
}
if(!flag) puts("-1");
}
return 0;
}