这个题的大致意思:是说你可以推一面墙,但是不能推两面墙,而且也不能推墙推过边界,问你最少要多少步才能走出迷宫。
这题的迷宫规模较小,好像可以搜索,但是直接搜又好像太慢了,所以可以用(IDA*)进行搜索。
关于估价函数的话,显然,最少也是要走到边界才能够走出迷宫,所以估价函数就是棋子走到边界的最近值。
由于在路途中可能会有障碍(指推不动的墙),所以估价函数一定是小于等于准确值的,正确性得到保证。
在搜索中用二进制来记录和更改墙的位置,例如1111代表四周都有墙。
就像这样:
int value(int x,int y)
{
return min(x-1,min(6-x,min(y-1,4-y)));
}
(IDA*)除了估价函数的构建,其他也就是一个搜索了,应该大家都会,就不在多讲。
说几个坑点:
1.题目中所给的数据的输入方式是反的,所以输入的时候要x,y反着输入
2.墙后有墙不能够推墙。
3.推了一个墙,有三个格子的墙会改变:
例如,最左边的格子的右墙被推了之后,中间格子的左墙就没有了,中间格子会多一个右墙,最右边的格子会多一个左墙,所以说有很多的地方需要更改。
4.走出去的那一步也要计算进路径中。
5.走的方向也有先后顺序:西北东南
#include<bits/stdc++.h>
using namespace std;
int a[7][7],minn,f[4][2]={{-1,0},{0,-1},{1,0},{0,1}},tx,ty;
bool flag;
char ch[200],dir[4]={'W','N','E','S'};
int value(int x,int y)//估价函数
{
return min(x-1,min(6-x,min(y-1,4-y)));
}
bool check(int x,int y)
{
if((x==1&&(!(a[x][y]&1)))||(x==6&&(!(a[x][y]&4)))||(y==1&&(!(a[x][y]&2)))||(y==4&&(!(a[x][y]&8))))
{
return 1;
}
return 0;
}
void dfs(int x,int y,int step,int last)//IDA*
{
if(step+value(x,y)>minn||flag)
{
return;
}
if(check(x,y))//最后一步
{
flag=1;
if(x==1&&(!(a[x][y]&1)))
{
ch[step]='W';
}
if(x==6&&(!(a[x][y]&4)))
{
ch[step]='E';
}
if(y==1&&(!(a[x][y]&2)))
{
ch[step]='N';
}
if(y==4&&(!(a[x][y]&8)))
{
ch[step]='S';
}
cout<<ch<<endl;
return;
}
for(int i=0;i<4;i++)
{
int xx=x+f[i][0],yy=y+f[i][1],xxx=xx+f[i][0],yyy=yy+f[i][1];
if(xx<1||xx>6||yy<1||yy>4||abs(last-i)==2||((a[x][y]&(1<<i))&&(a[xx][yy]&(1<<i))))
{
continue;
}
if(a[x][y]&(1<<i))//有墙且可以推
{
a[x][y]-=(1<<i);
a[xx][yy]+=(1<<i)-(1<<((i+2)%4));
a[xxx][yyy]+=(1<<((i+2)%4));
ch[step]=dir[i];
dfs(xx,yy,step+1,i);
if(flag)
{
return;
}
ch[step]=0;
a[x][y]+=(1<<i);
a[xx][yy]-=(1<<i)-(1<<((i+2)%4));
a[xxx][yyy]-=(1<<((i+2)%4));
}else{
ch[step]=dir[i];//无墙
dfs(xx,yy,step+1,i);
if(flag)
{
return;
}
ch[step]=0;
}
}
}
int main()
{
while(scanf("%d%d",&tx,&ty)&&(tx||ty))
{
flag=0;
for(int i=1;i<=4;i++)//反着输入
{
for(int j=1;j<=6;j++)
{
scanf("%d",&a[j][i]);
}
}
for(minn=1;;minn++)
{
memset(ch,0,sizeof(ch));
dfs(tx,ty,0,44);
if(flag)
{
break;
}
}
}
return 0;
}
/*
3 1
5 2 6 12 6 9
14 2 7 2 10 14
8 4 12 4 4 8
12 6 6 14 4 12
0 0
*/