//首先把每个在能走点走出去的最小步数求出并保存
//在进行dfs时,求h()时,即是求当前存在的节点走出去的最小步数中最大者
//其他地方和IDA*题一样处理即可,此题就是多了个预处理,首先在记忆化搜索一遍,然后在IDA*
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#define inf 12345678
using namespace std;
int n,m,t;
char map[9][9];
char dir[5][10]={"east","north","south","west"};
int dx[4]={0,-1,1,0},dis[9][9];
int dy[4]={1,0,0,-1};
int path[1000];
struct TPoint
{
int x,y;
TPoint(){}
TPoint(int _x,int _y):x(_x),y(_y){}
}st,en;
queue<TPoint>tpl;
void addedge(int u,int v,int val)
{
dis[u][v]=val;
tpl.push(TPoint(u,v));
}
bool ismap(int x,int y)
{
return x>=0&&x<n&&y>=0&&y<n;
}
bool onedge(int x,int y)
{
return x==0||y==0||x==n-1||y==n-1;
}
void bfs()
{
int i;
while(!tpl.empty())
{
st=tpl.front(),tpl.pop();
for(i=0;i<4;i++)
{
en.x=st.x+dx[i],en.y=st.y+dy[i];
if(!ismap(en.x,en.y)) continue;
if(!map[en.x][en.y]) continue;
if(dis[en.x][en.y]>dis[st.x][st.y]+1)
{
dis[en.x][en.y]=dis[st.x][st.y]+1;
tpl.push(en);
}
}
}
}
void init()
{
int i,j;
while(!tpl.empty()) tpl.pop();
for(i=0;i<n;i++) for(j=0;j<n;j++)
{
dis[i][j]=inf;
map[i][j]=map[i][j]=='1'?0:1;
if(!map[i][j]) continue;
if(onedge(i,j)) addedge(i,j,0);
}
bfs();
}
int h(char mid[9][9])
{
int i,j,maxf=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(mid[i][j]) maxf=max(maxf,dis[i][j]);
}
}
return maxf;
}
bool dfs(char mid[9][9],int dep)
{
if(dep+h(mid)>t) return 0;
if(dep==t) return 1;
int i,j,k,l,r;
char cvs[9][9];
for(i=0;i<4;i++)
{
memset(cvs,0,sizeof(cvs));
for(j=0;j<n;j++) for(k=0;k<n;k++)
{
if(onedge(j,k)||!mid[j][k]) continue;
l=j+dx[i],r=k+dy[i];
if(!map[l][r]) cvs[j][k]=1;
else cvs[l][r]=1;
}
path[dep]=i;
if(dfs(cvs,dep+1)) return 1;
}
return 0;
}
int main()
{
int i,end=0;
while(scanf("%d",&n)!=EOF)
{
if(end++) puts("");
for(i=0;i<n;i++) scanf("%s",map[i]);
init();
for(t=0;;t++)
{
if(dfs(map,0)) break;
}
for(i=0;i<t;i++) printf("%s\n",dir[path[i]]);
}
return 0;
}
hdu1813---IDA*
最新推荐文章于 2012-04-01 18:28:16 发布