您的位置:首页 > 其它

北大 acm 3083解题报告--dfs与bfs的运用

2013-09-04 11:11 453 查看
    题目:http://poj.org/problem?id=3083

    题目的大意就是:输入一个类似迷宫的东西,其中S表示起点,E表示终点,#表示墙壁,,表示空地。其中S,E一定在边缘,并且S一定能到达E

    例如:    

########
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S#E####


    求人从S出发,到达E的过程需要走几步?走的方式有三种,靠左走,靠右走,以及最短路径的走法,分别输出步数

    以上面的输入为例,靠左走:37步; 靠右走:5步; 最短:5步

    最短路径的肯定采用bfs;

    重点理解是靠左走,靠右走;

    假设我们 下 ,左 ,上 ,右  四个方向编号为 0,1 , 2,3

   靠左走分四种情况:

    (1)目前的行走朝向是  上 ,则考虑的朝向的优先级(由高到低),左,上,右,下   ; 对应编号: 2 ,    1   2  3  0

    (2)目前的行走朝向是  下  ,则考虑的朝向的优先级(由高到低),右,下,左,上   ;对应编号: 0 ,    3   0  1  2

    (3)目前的行走朝向是  右  ,则考虑的朝向的优先级(由高到低),上,右,下,左   ;对应编号: 3 ,    2   3  0  1

    (4)目前的行走朝向是  左  ,则考虑的朝向的优先级(由高到低),下,左,上,右  ; 对应编号:  1 ,    0  1   2  3

  靠右走分四种情况:

    (1)目前的行走朝向是  上 ,则考虑的朝向的优先级(由高到低),右,上,左,下   ;对应编号: 2 ,    3   2  1  0

    (2)目前的行走朝向是  下  ,则考虑的朝向的优先级(由高到低),左,下,右,上  ;对应编号: 0 ,    1   0  3  2

    (3)目前的行走朝向是  右  ,则考虑的朝向的优先级(由高到低),下,右,上,左  ;对应编号: 3 ,    0   3  2  1

    (4)目前的行走朝向是  左  ,则考虑的朝向的优先级(由高到低),上,左,下,右 ;对应编号:  1 ,    2   1  0  3

    假设当前的朝向编号为m,朝向的编号最高优先级为n;

    则:

    靠左走:n=(m+3)%4;    n=(n+1)%4;

    靠右走:n=(m+1)%4;    n=(n+3)%4;

    源码实现如下:

   //3083
#include<iostream>
#include <cstring>
using namespace std;

const int N=45;
typedef struct _node
{
int x;
int y;
}Node;
char maze

;
int visited

;
int dir[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
int w,h;
Node Q[N*N];
int Pre

[2];
int direct;

bool ldfs(int x, int y, int step)
{
if (maze[x][y] == 'E')
{
cout<<step<<" ";
return true;
}
direct = (direct + 3) % 4; //靠左手边走
while(1)
{
int tmpx=x + dir[direct][0];
int tmpy=y + dir[direct][1];
if (tmpx<h&&tmpx>=0&&tmpy<w&&tmpy>=0)
{
if (maze[tmpx][tmpy]=='.'||maze[tmpx][tmpy]=='E')
{
if(ldfs(tmpx, tmpy, step + 1)) return true;
}
}
direct = (direct + 1) % 4; //顺时针
}
}
bool rdfs(int x, int y, int step)
{
if (maze[x][y] == 'E')
{
cout<<step<<" ";
return true;
}
direct = (direct + 1) % 4; //靠右手边走
while(1)
{
int tmpx=x + dir[direct][0];
int tmpy=y + dir[direct][1];
if (tmpx<h&&tmpx>=0&&tmpy<w&&tmpy>=0)
{
if (maze[tmpx][tmpy]=='.'||maze[tmpx][tmpy]=='E')
{
if(rdfs(tmpx, tmpy, step + 1)) return true;
}
}
direct = (direct + 3) % 4; //逆时针
}
}
int BFS(int r,int c)
{
visited[r][c] = 1;
Node node; node.x=r; node.y=c;
Q[0]=node;
int first=-1,last=0;
int cnt=0;
while(first!=last)
{
Node v=Q[++first];
for (int i=0;i<4;i++)
{
int x=v.x+dir[i][0];
int y=v.y+dir[i][1];
if (x<h&&x>=0&&y<w&&y>=0)
{
if ((maze[x][y]=='.'||maze[x][y]=='E')&&(visited[x][y]==0))
{
node.x=x;node.y=y;
Pre[x][y][0]=v.x;
Pre[x][y][1]=v.y;
Q[++last]=node;
visited[x][y] = 1;
}
if (maze[x][y]=='E')
{
int x0,y0;
x0=Q[last].x;
y0=Q[last].y;
while (x0!=-1)
{
cnt++;
int tmp=x0;
x0=Pre[x0][y0][0];
y0=Pre[tmp][y0][1];
}
return cnt;
}
}
}
}
}

int main()
{
int n,i,j;
cin>>n;
while (n--)
{
cin>>w>>h;
memset(visited,0,sizeof(visited));
int r,c;
for (i=0;i<h;i++)
{
for (j=0;j<w;j++)
{
cin>>maze[i][j];
if (maze[i][j]=='S')
{
r=i;c=j;
}
}
}
direct = 0; ldfs(r, c, 1);
direct = 0; rdfs(r, c, 1);
Pre[r][c][0]=-1;
Pre[r][c][1]=-1;
cout<<BFS(r,c)<<endl;
}
return 0;
}

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  pku acm 3083 dfs bfs