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; }