Escape
 
Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
 Total Submission(s): 793    Accepted Submission(s): 329 
Problem Description
 
  You find yourself trapped in a large rectangular room, made up of large square tiles; some are accessible, others are blocked by obstacles or walls. With a single step, you can move from one tile to another tile if it is horizontally or vertically adjacent (i.e. you cannot move diagonally). 
 
 To shake off any people following you, you do not want to move in a straight line. In fact, you want to take a turn at every opportunity, never moving in any single direction longer than strictly necessary. This means that if, for example, you enter a tile from the south, you will turn either left or right, leaving to the west or the east. Only if both directions are blocked, will you move on straight ahead. You never turn around and go back! 
 
 Given a map of the room and your starting location, figure out how long it will take you to escape (that is: reach the edge of the room). 
 
 
  

 
 
 
 
Input
 
  On the first line an integer t (1 <= t <= 100): the number of test cases. Then for each test case: 
 
 a line with two integers separated by a space, h and w (1 <= h, w <= 80), the height and width of the room;  
 then h lines, each containing w characters, describing the room. Each character is one of . (period; an accessible space), # (a blocked space) or @ (your starting location).  
 There will be exactly one @ character in each room description.  
 
 
Output
 
  For each test case: 
 
 A line with an integer: the minimal number of steps necessary to reach the edge of the room, or -1 if no escape is possible.  
 
 
Sample Input
 
2 9 13 ############# #@..........# #####.#.#.#.# #...........# #.#.#.#.#.#.# #.#.......#.# #.#.#.#.#.#.# #...........# #####.####### 4 6 #.#### #.#.## #...@# ######
 
 
Sample Output
 
31 -1
 
 
Source
 
bapc2007_pre
 
  题目分析:裸的bfs,细心一点,按题意模拟即可 
 
    
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstdio>
#define MAX 87
using namespace std;
int t,h,w,sx,sy;
char mp[MAX][MAX];
int mark[5][MAX][MAX];
struct Node
{
    int x,y,t,d;
    Node ( int a , int b , int c , int x )
        :x(a),y(b),t(c),d(x){}
};
int dx[]={0,1,0,-1,0};
int dy[]={0,0,1,0,-1};
int bfs ( )
{
    queue<Node> q;
    q.push ( Node ( sx , sy , 0 , 0 ) );
    memset ( mark , -1 , sizeof ( mark ) );
    mark[0][sx][sy] = mark[1][sx][sy] = mark[2][sx][sy]
    = mark[3][sx][sy] = mark[4][sx][sy] = 0;
    while ( !q.empty())
    {
        int x = q.front().x , y = q.front().y;
        int t = q.front().t , d = q.front().d;
        q.pop();
        if ( x == 1 || x == h || y == 1 || y == w )
            return t;
        bool flag = true;
        for ( int i = 1 ; i < 5 ; i++ )
            if ( d == 0 || ( d%2 != i%2 ) )
            {
                int tx = x + dx[i] , ty = y + dy[i];
                if ( mp[tx][ty] != -1 )
                {
                    flag = false;
                    if ( mark[i][tx][ty] == -1 )
                    {
                        q.push ( Node ( tx ,ty , t+1 , i ) );
                        mark[i][tx][ty] = t+1;
                    }
                }
            }
        int tx = x + dx[d] , ty = y + dy[d];
        if ( flag && mp[tx][ty] != -1 && mark[d][tx][ty] == -1 )
        {
            q.push ( Node ( tx , ty , t+1 , d ) );
            mark[d][tx][ty] = t+1;
        }           
    }
    return -1;
}
int main ( )
{
    scanf ( "%d" , &t );
    char s[500];
    while ( t-- )
    {
        scanf ( "%d%d" , &h , &w );
        memset ( mp , -1 , sizeof ( mp ) );
        for ( int i = 1 ; i <= h ; i++ )
        {
            scanf ( "%s" , s+1 );
            for ( int j = 1 ; j <= w ; j++ )
                if ( s[j] == '.' ) mp[i][j] = 1;
                else if ( s[j] == '@' ) sx = i,sy = j,mp[i][j] = 1;
        }
        printf ( "%d\n" , bfs () );
    }
}  










