您的位置:首页 > 其它

poj 2935 Basic Wall Maze

2014-04-30 23:00 344 查看
Basic Wall Maze

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 2738Accepted: 1244Special Judge
Description

In this problem you have to solve a very simple maze consisting of:

a 6 by 6 grid of unit squares
3 walls of length between 1 and 6 which are placed either horizontally or vertically to separate squares
one start and one end marker

A maze may look like this:



You have to find a shortest path between the square with the start marker and the square with the end marker. Only moves between adjacent grid squares are allowed; adjacent means that the grid squares share an edge and are not separated by a wall. It is
not allowed to leave the grid.

Input

The input consists of several test cases. Each test case consists of five lines: The first line contains the column and row number of the square with the start marker, the second line the column and row number of the square with the end marker. The third,
fourth and fifth lines specify the locations of the three walls. The location of a wall is specified by either the position of its left end point followed by the position of its right end point (in case of a horizontal wall) or the position of its upper end
point followed by the position of its lower end point (in case of a vertical wall). The position of a wall end point is given as the distance from the left side of the grid followed by the distance from the upper side of the grid.

You may assume that the three walls don’t intersect with each other, although they may touch at some grid corner, and that the wall endpoints are on the grid. Moreover, there will always be a valid path from the start marker to the end marker. Note that
the sample input specifies the maze from the picture above.

The last test case is followed by a line containing two zeros.

Output

For each test case print a description of a shortest path from the start marker to the end marker. The description should specify the direction of every move (‘N’ for up, ‘E’ for right, ‘S’ for down and ‘W’ for left).

There can be more than one shortest path, in this case you can print any of them.

Sample Input
1 6
2 6
0 0 1 0
1 5 1 6
1 5 3 5
0 0

Sample Output
NEEESWW

Source

Ulm Local 2006
题意:给你一个6*6的迷宫,告诉你3堵墙的位置,起点和终点的坐标,墙可能是横的 ,也可能是竖的,然后输出从起始位置到目标位置的最短路径,如果有多条最短路径,输出一条即可。

分析:本题有两个相对较难的地方。第一个是记录路径,我的方法是先用bfs搜出最短的时间,再用dfs搜出具体的最短路径;第二个是如何处理墙,要看能不能从墙那里通过,应该先判断墙是横的还是竖的,然后再根据现在的坐标判断会不会被墙挡住。详见代码。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
#define maxn 20
#define INF 10000000
int dir[5][5] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
char way[50];
bool used[maxn][maxn] , escape;
int mintime[maxn][maxn];///到达每个位置所需的最短时间。
int mint;
int vis[50][50];
char link[100];///记录路径的数组。
char ch[4] = {'S','N','E','W'};
struct point
{
int x;
int y;
int time;
int step;

} wall[5][2];

point start , End;

int max(int a, int b)
{
return a>b?a:b;
}

int Min(int a, int b)
{
return a<b?a:b;
}

int judge( int x , int y , int x1 , int y1 )///判断从(x,y)到(x1,y1)是否会被墙挡住。
{
int flag = 1;
for( int i=0; i<3; i++ )
{
if( wall[i][0].x == wall[i][1].x )///判断墙是横的还是竖的。
{
if( y == y1
&& y <= max( wall[i][0].y , wall[i][1].y )
&& y >= (Min( wall[i][0].y , wall[i][1].y) + 1 )
&& wall[i][0].x == Min( x , x1 ) )
{
flag = 0;
break;
}
}
if( wall[i][0].y == wall[i][1].y )
{
if( x == x1
&& x <= max( wall[i][0].x , wall[i][1].x )
&& x >= (Min( wall[i][0].x , wall[i][1].x ) + 1 )
&& wall[i][0].y == Min( y , y1 ) )
{
flag = 0;
break;
}
}
}
return flag;
}

queue<point> Q;

void dfs( int step , int x , int y )
{
int i , temp;
if( x<1 || x>6 || y<1 || y>6  ) return;
if( x == End.x && y == End.y && step == mint )
{
escape = 1;
for( int i=1; i<=mint; i++ )
printf("%c",link[i]);
printf("\n");
return;
}
if(step >= mint) return;///大于最短时间,不用再搜。
if( step  + abs( x - End.x ) + abs( y - End.y ) > mint  )return;
///剪枝。当前步数加上最短还需要的步数,如果大于最短时间,不用再搜
for( i=0; i<4; i++ )
{
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if( judge( x, y , xx , yy ) )
{
vis[xx][yy] = 1;
link[step+1] = ch[i];
dfs( step+1, xx , yy  );
if(escape) return ;
vis[xx][yy] = 0;
/** if( escape )
{
if( i == 0 ) printf("R");
else if( i == 1 ) printf("W");
else if( i == 2 ) printf("N");
else if( i == 3 ) printf("S");
return;
}
**/
}
}
return;
}

int bfs( point s )
{
int i;
memset(used, 0, sizeof(used));
Q.push( s );
point hd;
while( !Q.empty() )
{
hd = Q.front();
Q.pop();
///        if( hd.x == End.x && hd.y == End.y )
///return 0;
for( i=0; i<4; i++ )
{
int x = hd.x + dir[i][0];
int y = hd.y + dir[i][1];
///           printf("%d %d %d %d\n",x , y , hd.x , hd.y);
if( x>=1 && x<=6 && y>=1 && y<=6 && judge( x , y , hd.x , hd.y ) && !used[x][y] )
{
point t;
t.x = x;
t.y = y;
t.time = hd.time + 1;
///                printf("   %d    %d\n\n", t.time, mintime[x][y]);
if( t.time < mintime[x][y] )
{
///                   printf("fasdfasdfadf\n");
mintime[x][y] = t.time;
used[x][y] = 1;
Q.push( t );
}
}
}
}
return mintime[End.x][End.y];///用bfs搜出最短时间。
}

int main()
{

while( scanf("%d%d", &start.y, &start.x) && ( start.x + start.y ) )
{
scanf("%d%d", &End.y, &End.x);
for( int i=0; i<3; i++ )
{
scanf("%d%d%d%d", &wall[i][0].y, &wall[i][0].x, &wall[i][1].y, &wall[i][1].x );
}
start.time = 0;
for( int i=0; i<maxn; i++ )
{
for( int j=0; j<maxn; j++ )
{
mintime[i][j] = INF;
}
}
mintime[start.x][start.y] = 0;
mint = bfs( start );
///printf("mint==%d\n",mint);
escape = 0;
memset(vis,0,sizeof(vis));
dfs( 0 , start.x , start.y );///在知道最短时间的情况下,用dfs搜出最短路径。
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: