Hdu 2364 Escape

Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=2364

 

这道题的特殊之处在于能转弯时不能直走,必须转弯,所以在行走时,要判断能否转弯,不能转弯时才选择直走。

因为是一道走迷宫的题,所以可以用BFS解决问题。

有一点需要注意:起点也有可能是终点,所以在判断是否到终点时,最好判断该点是不是'#',而不该判断是不是'.',因为终点有可能是'@'

 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>

using namespace std;

const int NEVERCOME = -1;
const int NORTH = 0;
const int SOUTH = 2;
const int WEST = 1;
const int EAST = 3;

const int MAXN = 80 + 5;
int vis[MAXN][MAXN][5]; // the first param means x, the second one means y
                        // the third one means dir
char maze[MAXN][MAXN]; // record the maze
int moveToDir[4][2];

int Bfs( int height, int width,  int startX, int startY );
bool isEnd( int &height, int &width,  int &x, int &y ); // judge whether the person has reached the end point
bool isInside( int &height, int &width,  int &x, int &y ); // judge whether the person has reached the end point

int main()
{
    // dir
    moveToDir[NORTH][0] = -1;
    moveToDir[NORTH][1] = 0;

    moveToDir[SOUTH][0] = 1;
    moveToDir[SOUTH][1] = 0;

    moveToDir[WEST][0] = 0;
    moveToDir[WEST][1] = -1;

    moveToDir[EAST][0] = 0;
    moveToDir[EAST][1] = 1;

    int T;
    cin >> T;
    int height, width;
    int i, j;
    int startX, startY;
    while( T-- ) {
        scanf( "%d%d", &height, &width );
        for( i=0; i<height; i++ ) {
            getchar();
            for( j=0; j<width; j++ ) {
                scanf( "%c", &maze[i][j] );
                if( maze[i][j]=='@' ) {
                    startX = i;
                    startY = j;
                }
                //printf( "%c", maze[i][j] );
            }
            //printf("\n");
        }
        printf( "%d\n", Bfs( height, width, startX, startY ) );
    }
    return 0;
}

typedef struct Node{
    int x, y;
    int step;
    int dir; // means the dir the person facing
}Node;

int Bfs( int height, int width,  int startX, int startY ) {
    queue <Node> q;
    Node t, next;
    t.x = startX;
    t.y = startY;
    t.step = 0;

    memset( vis, NEVERCOME, sizeof(vis) );
    int i, j;
    // the four directions
    t.dir = NORTH;
    vis[t.x][t.y][t.dir] = 0;
    q.push( t );

    t.dir = SOUTH;
    vis[t.x][t.y][t.dir] = 0;
    q.push( t );

    t.dir = WEST;
    vis[t.x][t.y][t.dir] = 0;
    q.push( t );

    t.dir = EAST;
    vis[t.x][t.y][t.dir] = 0;
    q.push( t );

    while( !q.empty() ) {
        t = q.front();
        q.pop();

        if( isEnd( height, width, t.x, t.y ) ) {
            return t.step;
        }
        int i;
        bool flag = false;
        // can the person go left or right
        for( i=0; i<4;i++ ) {
            if( (i&1) != ( t.dir&1 ) ) { // need to turn
                next.x = t.x + moveToDir[i][0];
                next.y = t.y + moveToDir[i][1];
                next.step = t.step + 1;
                next.dir = i;

                if( isInside( height, width, next.x, next.y ) ) {
                    flag = true;
                    if( vis[next.x][next.y][next.dir]==-1 || next.step<vis[next.x][next.y][next.dir] ) {
                        q.push(next);
                        vis[next.x][next.y][next.dir] = next.step;
                    }
                }
            }
        }

        // should go straight ?
        if( flag == false ) {
            next.x = t.x + moveToDir[t.dir][0];
            next.y = t.y + moveToDir[t.dir][1];
            next.step = t.step + 1;
            next.dir = t.dir;

            if( isInside( height, width, next.x, next.y ) ) {
                 if( vis[next.x][next.y][next.dir]==-1 || next.step<vis[next.x][next.y][next.dir] ) {
                    q.push(next);
                    vis[next.x][next.y][next.dir] = next.step;
                }
            }

        }
    }

    return -1;
}

bool isEnd( int &height, int &width,  int &x, int &y ) {
    if( maze[x][y] != '#' ) {
        if( ( x==0 || x==height-1 ) || ( y==0 || y==width-1) ) {
            return true;
        }
    }
    return false;
}

bool isInside( int &height, int &width,  int &x, int &y ) {
    if( maze[x][y] == '.' ) {
        if( x>=0 && x<height && y>=0 && y<width ) {
            return true;
        }
    }
    return false;
}

 

 

posted @ 2015-03-07 17:45  Emerald  阅读(120)  评论(0编辑  收藏  举报