一道IDA*的题,估价函数用popoqqq神犇的。以当前棋盘与目标棋盘有几个不同位置-1作为估价。
如果当前步数+估价大于深度即退出,没有什么神奇的操作。。
#include <cstdio>
#define C (c=getchar())
using namespace std;
int t,x,y;
char map[7][7];
char c;
bool f;
const int dx[10]={0,1,1,-1,-1,2,2,-2,-2};
const int dy[10]={0,2,-2,2,-2,1,-1,1,-1};
char target[7][7]={
"000000",
"011111",
"001111",
"000*11",
"000001",
"000000"
};
inline void swap(char &a,char &b)
{
char c=a;
a=b;
b=c;
return ;
}
int gj()
{
register int i,j;
int ans=0;
for(i=1;i<=5;i++)
for(j=1;j<=5;j++)
if (map[i][j]!=target[i][j]) ans++;
return ans-1;
}
void ida(int x,int y,int now ,int ma)
{
register int i;
int mi=gj();
if (mi==-1)
{
f=1;
return;
}
if(mi+now>ma) return;
for (i=1;i<=8;i++)
{
int x_=x+dx[i];
int y_=y+dy[i];
if(x_<=0||y_<=0||x_>5||y_>5) continue;
swap(map[x][y],map[x_][y_]);
ida(x_,y_,now+1,ma);
swap(map[x][y],map[x_][y_]);
if(f) return;
}
}
int main()
{
register int i,j,k;
scanf("%d",&t);
for (k=1;k<=t;k++)
{
f=0;
for (i=1;i<=5;i++)
for (j=1;j<=5;j++)
{
C;while (c!='0'&&c!='1'&&c!='*') C;
map[i][j]=c;
if (c=='*') x=i,y=j;
}
for (i=0;i<=15;i++)
{
ida(x,y,0,i);
if (f) break;
}
if (i==16) printf("-1\n");
else printf("%d\n",i);
}
return 0;
}