题目大意:给出一个迷宫,#表示墙,S表示起点,E表示终点。求从S到E的优先靠左边的墙走、优先靠右边的墙走和S到E的最短路径。
思路:考虑向左向右用DFS,最短路径用BFS。注意几点,一是尽量不用递归,开始用的递归,BFS会栈溢出,改用队列实现后没问题,而且其实逻辑上反而更统一,这里DFS还好,递归没有问题,大概是因为有向左向右的规则,并不是一味地遍历所有状态;再一个就是BFS实在是状态太多,必须限制,可以标记会走的点,不让这些点重复地进入队列。
当然,这个代码明显有很多可以修改的地方,在写的过程中由于偷懒不影响结果的就没改了。主要是练手而已,重在细心。
代码:
#include<stdio.h>
#include <stdlib.h>
#include "queue"
using namespace std;
#define LEN 42//最外层不通
typedef struct {
int x,y;
int dx,dy;
int layer;
} NODE;
char maze[LEN][LEN];
int w,h;
int ln,rn,sn;
void ini_maze(int *sx , int *sy)
{
int i,j;
for(i=0;i < LEN ; i++)
for(j=0; j < LEN ; j++)
maze[i][j]='#';
for(i=1; i<=h; i++)
{
getchar();
for(j=1; j<=w; j++)
{
scanf("%c",&maze[j][i]);
if('S' == maze[j][i])
{
*sx = j;
*sy = i;
}
}
}
ln = 1; rn =1; sn = 5001;
}
void find_sway(int x, int y, int dx, int dy , int layer)
{
int lres = -1, rres = -1, mres = -1;
NODE nod,td;
queue<NODE> qlist;
x += dx;
y += dy;
while(maze[x][y] != 'E')
{
if( maze[x+dy][y-dx] != '#') //向左
{
nod.dx = dy;
nod.dy = -dx;
nod.x = x;
nod.y = y;
nod.layer = layer+1;
qlist.push(nod);
if(maze[x+dy][y-dx] != 'E')
maze[x+dy][y-dx] = '#';
}
if( maze[x-dy][y+dx] != '#') //向右
{
nod.dx = -dy;
nod.dy = dx;
nod.x = x;
nod.y = y;
nod.layer = layer+1;
qlist.push(nod);
if(maze[x-dy][y+dx] != 'E')
maze[x-dy][y+dx] = '#';
}
if( maze[x+dx][y+dy] != '#') //向前
{
nod.dx = dx;
nod.dy = dy;
nod.x = x;
nod.y = y;
nod.layer = layer+1;
qlist.push(nod);
if(maze[x+dx][y+dy] != 'E')
maze[x+dx][y+dy] = '#';
}
td = qlist.front();
x = td.x + td.dx;
y = td.y + td.dy;
dx = td.dx;
dy = td.dy;
layer = td.layer;
qlist.pop();
}
sn = layer;
}
int find_lway(int x, int y, int dx, int dy , int layer)
{
int lres = -1, rres = -1, mres = -1;
ln++;
x += dx;
y += dy;
if( maze[x][y] == 'E')
{
return layer;
}
if( maze[x+dy][y-dx] != '#') //向左
{
lres = find_lway(x,y,dy,-dx,layer+1);
if(lres == -1)
ln++;
}
if(lres == -1)
{
if( maze[x+dx][y+dy] != '#') //向前
{
mres = find_lway(x,y,dx,dy,layer+1);
if(mres == -1)
ln++;
}
if(mres == -1)
{
if( maze[x-dy][y+dx] != '#') //向右
{
rres = find_lway(x,y,-dy,dx,layer+1);
if(rres == -1)
ln++;
}
if(rres == -1)
{
return -1;
}
}
}
return 0;
}
int find_rway(int x, int y, int dx, int dy , int layer)
{
int lres = -1, rres = -1, mres = -1;
rn++;
x += dx;
y += dy;
if( maze[x][y] == 'E')
{
return layer;
}
if( maze[x-dy][y+dx] != '#') //right
{
rres = find_rway(x,y,-dy,dx,layer+1);
if(rres == -1)
rn++;
}
if(rres == -1)
{
if( maze[x+dx][y+dy] != '#') //向前
{
mres = find_rway(x,y,dx,dy,layer+1);
if(mres == -1)
rn++;
}
if(mres == -1)
{
if( maze[x+dy][y-dx] != '#') //left
{
lres = find_rway(x,y,dy,-dx,layer+1);
if(lres == -1)
rn++;
}
if(lres == -1)
{
return -1;
}
}
}
return 0;
}
int main()
{
int sx , sy,i,n;
// freopen("in.txt","r",stdin);
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d%d",&w,&h);
ini_maze(&sx,&sy);
if(1 == sx)
{
find_lway(sx,sy,1,0,2);
find_rway(sx,sy,1,0,2);
find_sway(sx,sy,1,0,2);
}
if(1 == sy)
{
find_lway(sx,sy,0,1,2);
find_rway(sx,sy,0,1,2);
find_sway(sx,sy,0,1,2);
}
if(w == sx)
{
find_lway(sx,sy,-1,0,2);
find_rway(sx,sy,-1,0,2);
find_sway(sx,sy,-1,0,2);
}
if(h == sy)
{
find_lway(sx,sy,0,-1,2);
find_rway(sx,sy,0,-1,2);
find_sway(sx,sy,0,-1,2);
}
printf("%d %d %d\n",ln,rn,sn);
}
system("pause");
return 0;
}