解题报告POJ2935
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
解题报告POJ2935
Basic Wall Maze
Time Limit: 1000MS Memory Limit: 65536K
Description
In this problem you have to solve a very simple maze consisting of:
1. a 6 by 6 grid of unit squares
2. 3 walls of length between 1 and 6 which are placed either horizontally or vertically to
separate squares
3.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 th ey 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’ f or 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
简单的迷宫问题(Basic Wall Maze)
题目描述:
在本题中,你需要求解一个简单的迷宫问题:
1) 迷宫由6行6列的方格组成;
2) 3堵长度为1~6的墙壁,水平或竖直地放置在迷宫中,用于分隔方格;
3) 一个起始位置和目标位置。
如下面的图2.23描述了一个迷宫。
你需要找一条从起始位置到目标位置的最短路径。
从任一个方格出发,只能移动到上、下、左、右相邻方格,并且没有被墙壁所阻挡。
输入描述:
输入文件中包含多个测试数据。
每个测试数据包含5行:第1行为两个整数,表示起始位置的列号和行号;第2行也是两个整数,为目标位置的列号和行号,列号和行号均从1开始记起。
;第3~5行均为4个整数,描述了3堵墙的位置;如果墙是水平放置的,则由左、右两个端点所在的位置指定,如果墙是竖直放置的,则由上、下两个端点所在的位置指定;端点的位置由两个整数表示,第1个整数表示端点距离迷宫左边界的距离,第2个整数表示端点距离迷宫上边界的距离。
假定这3堵墙互相不会交叉,但两堵墙可能会相邻于某个方格的顶点。
从起始位置到目标位置一定存在路径。
下面的样例输入数据描述了图2.23所示的迷宫。
输入文件中最后一行为两个0,代表输入结束。
输入描述:
对输入文件中的每个测试数据,输出从起始位置到目标位置的最短路径,最短路径由代表每一步移动的字符组成('N'表示向上移动,'E'表示向右移动,'S'表示向下移动,'W'表示向左移动)。
对某个测试数据,可能存在多条最短路径,对于这种情形,只需输入任意一条最短路径即可。
样例输入:
1 6
2 6
0 0 1 0
1 5 1 6
1 5 3 5
0 0
样例输出:
NEEESWW
Source:Ulm Local 2006
题目类型:BFS搜索,图论
解题思路:
这题是经典的图论BFS遍历问题。
地图6*6,并且告诉你起点和重点,求最短步数。
普通的BFS。
此题的关键在于处理三堵墙。
强是地图中两个结点的边界。
怎么处理:
第一种策略:MAP[][]数组开大一半,将墙也看成结点,有墙的地方设置‘#’,表示无法通行,否则可自由通过。
需要注意的是,这样map的下标和实际的下标会有两倍关系,需要转换。
第二种策略:额外开辟一个三维数组int map[7][7][4]描述每个点是否在四个方向上能走通。
Map[i][j][k]表示(i,j)坐标的四个方向k(k:0上1右2下3左)是否有墙阻挡,若有则置1。
将墙处理好后便可用队列模拟BFS达到最短步数的目的。
代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define R(x,y) x>=1&&x<7&&y>=1&&y<7//从1开始记起
int map[7][7][4];//描述每个点是否在四个方向上能走通:0上1右2下3左
int sx,sy,ex,ey;//开始、结束坐标
struct Node
{
int x,y;//当前坐标
char step[40];//记录怎么走的
int num;
};
queue<Node> Q;
int dir[4][2]={{0,-1},{1,0},{0,1},{-1,0}};//四个方向
int visited[7][7];//标记是否已经访问过
void setwall(int x1,int y1,int x2,int y2)
{
if((x1==x2&&(x1==0||x1==6))||(y1==y2&&(y1==0||y1==6))) return ;//墙壁在外边界上,不用设置
int i;
if(x1==x2)
{
for(i=y1+1;i<=y2;i++)
{
map[x1][i][1]=1;//右
map[x1+1][i][3]=1;//左
}
}
else if(y1==y2)
{
for(i=x1+1;i<=x2;i++)
{
map[i][y1][2]=1;//下
map[i][y1+1][0]=1;//上
}
}
}
//普通的BFS
void bfs(Node st)
{
if(sx==ex&&sy==ey) {
printf("\n");
return ;
}
Node hd,tmp;
int i,x,y;
Q.push(st);
while(!Q.empty())
{
hd=Q.front();Q.pop();
for(i=0;i<4;i++)
{
x=hd.x+dir[i][0],y=hd.y+dir[i][1];
if(map[hd.x][hd.y][i]==0&&R(x,y)&&visited[x][y]==0)
{
visited[x][y]=1;
tmp.x=x,tmp.y=y;
strcpy(tmp.step,hd.step);//跟下一条语句交换顺序会出错,cpy函数‘\0’结束,会影响num的值?
tmp.num=hd.num+1;
if(i==0)tmp.step[tmp.num-1]='N';//上下左右的转换
else if(i==1) tmp.step[tmp.num-1]='E';
else if(i==2) tmp.step[tmp.num-1]='S';
else tmp.step[tmp.num-1]='W';
Q.push(tmp);
if(tmp.x==ex&&tmp.y==ey) //找到一个则输出
{
tmp.step[tmp.num]='\0';
puts(tmp.step);
return ;
}
}
}
}
}
int main()
{
int x1,y1,x2,y2;//墙的两个点坐标
while(scanf("%d%d",&sx,&sy))
{
if(sx==0&&sy==0) break;
memset(visited,0,sizeof(visited));
memset(map,0,sizeof(map));
scanf("%d%d",&ex,&ey);
int i;
for(i=0;i<3;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
setwall(x1,y1,x2,y2);
}
Node start;
start.x=sx,start.y=sy,start.num=0;
visited[sx][sy]=1;
bfs(start);
while(!Q.empty())
{
Q.pop();
}
}
return 0;
}。