題目大意:給出一個迷宮,#表示牆,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;
}