题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1813
IDA*:求出某个位置逃出的最少步数,然后在构造 h() 为所有点逃离迷宫的最少步数的最大值
IDA*:求出某个位置逃出的最少步数,然后在构造 h() 为所有点逃离迷宫的最少步数的最大值
#include<cstdio>
#include<cstring>
using namespace std;
int n;
bool maze[10][10];
int dir[4][2]={{0,1},{-1,0},{1,0},{0,-1}};
int ans[100];
int dis[10][10];
int deep;
struct S{
bool maze[10][10];
S(){memset(maze,false,sizeof(maze));}
}s;
inline bool h(int d,S ts){
for(int i=1;i<n-1;i++){
for(int j=1;j<n-1;j++){
if(!ts.maze[i][j]) continue;
if(dis[i][j]+d>deep){
return false;
}
}
}
return true;
}
bool dfs(int d,S tu){
if(!h(d,tu)) return false;
if(d==deep) return true;
for(int i=0;i<4;i++){
S tv;
for(int ii=1;ii<n-1;ii++){
for(int jj=1;jj<n-1;jj++){
if(!maze[ii][jj]) continue;
int tx=ii-dir[i][0];
int ty=jj-dir[i][1];
tv.maze[ii][jj]=tu.maze[tx][ty];
tx=ii+dir[i][0];
ty=jj+dir[i][1];
if(maze[tx][ty]) continue;
tv.maze[ii][jj]|=tu.maze[ii][jj];
}
}
ans[d]=i;
if(dfs(d+1,tv)) return true;
}
return false;
}
int que[1000][2];
void bfs(int x,int y){
dis[x][y]=0;
int ss=0,ee=0;
que[0][0]=x;
que[0][1]=y;
while(ss<=ee){
int ux=que[ss][0];
int uy=que[ss][1];
ss++;
for(int i=0;i<4;i++){
int tx=ux+dir[i][0];
int ty=uy+dir[i][1];
if(tx<=0||ty<=0||tx>=n-1||ty>=n-1) continue;
if(!maze[tx][ty]) continue;
if(dis[tx][ty]<=dis[ux][uy]+1) continue;
dis[tx][ty]=dis[ux][uy]+1;
ee++;
que[ee][0]=tx;
que[ee][1]=ty;
}
}
}
inline void in(bool& val){
char in=getchar();
while(in<=32) in=getchar();
val=(in=='0');
}
int main(){
bool flag=false;
while(~scanf("%d",&n)){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
in(maze[i][j]);
if(i*j&&i!=n-1&&j!=n-1){
s.maze[i][j]=maze[i][j];
}
}
}
if(n<=2){
puts("");
continue;
}
memset(dis,0x7f,sizeof(dis));
for(int i=0;i<n;i++){
if(maze[0][i]) bfs(0,i);
if(maze[n-1][i]) bfs(n-1,i);
if(maze[i][0]) bfs(i,0);
if(maze[i][n-1]) bfs(i,n-1);
}
deep=0;
while(true){
if(dfs(0,s)) break;
deep++;
}
if(flag) puts(""); flag=true;
for(int i=0;i<deep;i++){
if(ans[i]==0) puts("east");
else if(ans[i]==1) puts("north");
else if(ans[i]==2) puts("south");
else if(ans[i]==3) puts("west");
}
}
return 0;
}