题意:传送门
题解:要了解IDA*,首先需要了解迭代加深,
定义:每次限定一个maxdepmaxdep最大深度,使搜索树的深度不超过maxdepmaxdep。
使用范围:需要在有一定限制条件下使用
优点:可能会在一个没有解,或者很深的地方无限递归而题目种没有要求输出任何的一组解,所以限制一个深度,让它遍历更多的分治,去更广泛地求解。
其次需要了解估价函数
定义:f(n)=g(n)+h(n),其中f(n)是节点的估价函数,g(n)是现在的实际步数,h(n)是对未来步数的最完美估价。
最后A*是用于对BFS的优化,IDA*是对迭代加深的DFS的优化,本质上都是对BFS和DFS加上一个估价函数。
最后最重要的就是对估价函数的推导,推到的不好也就是h(n)=0,仍然相当于暴搜,推导的不好还可能WA。
附上代码:
#include<bits/stdc++.h>
using namespace std;
int ans[5][5]={{1,1,1,1,1},{0,1,1,1,1},{0,0,2,1,1},{0,0,0,0,1},{0,0,0,0,0}};
int xx[]={1,1,-1,-1,2,2,-2,-2};
int yy[]={2,-2,2,-2,1,-1,1,-1};
int T,k,a[5][5],flag;
char ch[10];
bool judge()
{
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
if(a[i][j]!=ans[i][j])return 0;
}
}
return 1;
}
bool eva(int s)
{
int v=0;
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
if(a[i][j]!=ans[i][j])v++;
}
}
if(s+v>k)return false;
else return true;
}
void search(int s,int x,int y)
{
if(s>k)return ;
if(s==k){if(judge())flag=1;return ;}
if(flag)return ;
for(int i=0;i<8;i++){
int nx=x+xx[i],ny=y+yy[i];
if(nx<0||nx>4||ny<0||ny>4)continue;
swap(a[x][y],a[nx][ny]);
if(eva(s))search(s+1,nx,ny);
swap(a[x][y],a[nx][ny]);
}
}
int main()
{
scanf("%d",&T);
while(T--){
int x,y;
for(int i=0;i<5;i++){
scanf("%s",ch);
for(int j=0;j<5;j++){
if(ch[j]!='*')a[i][j]=ch[j]-'0';
else x=i,y=j,a[i][j]=2;
}
}
for(k=1;k<=15;k++){
search(0,x,y);
if(flag){
printf("%d\n",k);
break;
}
}
if(!flag)printf("-1\n");
flag=0;
}
return 0;
}