Escape from Tetris
Time Limit : 12000/4000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 1 Accepted Submission(s) : 1
Problem Description
由于整日整夜地对着这个棋盘,Lele终于走火入魔。每天一睡觉,他就会梦到自己会被人被扔进一个棋盘中,一直找不到出路,然后从梦中惊醒。久而久之,Lele被搞得精神衰弱。梦境是否会成为现实,谁也说不准,不过不怕一万只怕万一。现在Lele每次看到一个棋盘,都会想象一下自己被关进去以后要如何逃生。
Lele碰到的棋盘都是正方形的,其中有些格子是坏的,不可以走,剩下的都是可以走的。只要一走到棋盘的边沿(最外面的一圈),就算已经逃脱了。Lele梦见自己一定会被扔在一个可以走的格子里,但是不确定具体是哪一个,所以他要做好被扔在任意一个格子的准备。
现在Lele请你帮忙,对于任意一个棋盘,找出一个最短的序列,序列里可以包括"north"(地图里向上),"east"(地图里向右),"south"(地图里向下),"west"(地图里向左),这四个方向命令。不论Lele被扔在棋盘里的哪个好的格子里,都能按这个序列行走逃出棋盘。
逃脱的具体方法是:不论Lele被扔在哪里,Lele按照序列里的方向命令一个一个地走,每个命令走一格,如果走的时候会碰到坏的格子,则忽略这条命令。当然,如果已经逃脱了,就可以不考虑序列中剩下的命令了。
Lele碰到的棋盘都是正方形的,其中有些格子是坏的,不可以走,剩下的都是可以走的。只要一走到棋盘的边沿(最外面的一圈),就算已经逃脱了。Lele梦见自己一定会被扔在一个可以走的格子里,但是不确定具体是哪一个,所以他要做好被扔在任意一个格子的准备。
现在Lele请你帮忙,对于任意一个棋盘,找出一个最短的序列,序列里可以包括"north"(地图里向上),"east"(地图里向右),"south"(地图里向下),"west"(地图里向左),这四个方向命令。不论Lele被扔在棋盘里的哪个好的格子里,都能按这个序列行走逃出棋盘。
逃脱的具体方法是:不论Lele被扔在哪里,Lele按照序列里的方向命令一个一个地走,每个命令走一格,如果走的时候会碰到坏的格子,则忽略这条命令。当然,如果已经逃脱了,就可以不考虑序列中剩下的命令了。
Input
本题目包含多组测试,请处理至文件结束。 每组测试第一行包含一个正整数 N (0<n<9),代表棋盘的大小是 n*n="" 接下来有n行,每行n个字符代表这个棋盘。="" 其中0代表该位置是好的,可以走,1代表该位置是坏的,不可以走。="" 题目数据保证,对于任意一个棋盘,都存在题目中所要求的序列="" <="" div="">
Output
对于每组数据,输出题目所要求的序列,序列中每个元素一行。 如果存在两个符合要求的序列,请输出字典序最小的那个序列。 两个测试之间请用一个空行隔开。
Sample Input
4 1101 0001 1100 1001
Sample Output
east north
Author
linle
Source
HDOJ 2007 Summer Exercise(2)
如题 IDA*
广搜获得每个可能降落点的预估值,由边广搜
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <string>
using namespace std;
int dir[4][2]= {0,1,-1,0,1,0,0,-1};
char Map[10][10];
int n,len,ll;
char ch[4][10]= {{"east"},{"north"},{"south"},{"west"}};
int vis[10][10],flag[1111];
struct node
{
int x,y;
bool cheak()
{
if(x>=0&&x<n&&y>=0&&y<n)
return true ;
return false ;
}
} a[111];
void bfs(int x,int y) //预处理估计值
{
node e;
e.x=x,e.y=y;
queue<node>q;
q.push(e);
vis[e.x][e.y]=0;
while(q.size())
{
e=q.front();
q.pop();
for(int i=0; i<4; i++)
{
node ee=e;
ee.x+=dir[i][0];
ee.y+=dir[i][1];
if(ee.cheak())
{
if(Map[ee.x][ee.y]=='0')
if(vis[ee.x][ee.y]==-1||vis[ee.x][ee.y]>vis[e.x][e.y]+1)
{
vis[ee.x][ee.y]=vis[e.x][e.y]+1;
q.push(ee);
}
}
}
}
return ;
}
int get_h(node * e)
{
int ans=0;
for(int i=0; i<len; i++)
{
ans=max(vis[e[i].x][e[i].y],ans);
}
return ans;
}
bool dfs(int length,node * e)
{
if(length<get_h(e))
return false ;
if(length==0)
return true ;
for(int i=0; i<4; i++)
{
node ee[111];
for(int j=0; j<len; j++)
{
ee[j]=e[j];
ee[j].x+=dir[i][0];
ee[j].y+=dir[i][1];
if(!ee[j].cheak()||e[j].x==0||e[j].y==0||e[j].x==n-1||e[j].y==n-1||Map[ee[j].x][ee[j].y]=='1') //没有达到出口
{
ee[j]=e[j];
}
}
flag[length]=i;
if(dfs(length-1,ee)) return true ;
}
return false ;
}
int main()
{
bool ant=false ;
while(~scanf("%d",&n))
{
if(ant) printf("\n");
ant=true ;
for(int i=0; i<n; i++)
{
getchar();
for(int j=0; j<n; j++)
scanf("%c",&Map[i][j]);
}
memset(vis,-1,sizeof(vis));
len=0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{
if(Map[i][j]=='0'&&(i==0||i==n-1||j==0||j==n-1))
bfs(i,j);
else if(Map[i][j]=='0')a[len].x=i,a[len++].y=j;
}
int length=get_h(a);
while(!dfs(length,a))
{
length++;
}
while(length--)
{
printf("%s\n",ch[flag[length+1]]);
}
}
return 0;
}