Children of the Candy Corn

                                                                Children of the Candy Corn

                                     Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)

Problem Description
The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and must wander through the maze facing zombies, chainsaw-wielding psychopaths, hippies, and other terrors on their quest to find the exit. 

One popular maze-walking strategy guarantees that the visitor will eventually find the exit. Simply choose either the right or left wall, and follow it. Of course, there's no guarantee which strategy (left or right) will be better, and the path taken is seldom the most efficient. (It also doesn't work on mazes with exits that are not on the edge; those types of mazes are not represented in this problem.) 

As the proprieter of a cornfield that is about to be converted into a maze, you'd like to have a computer program that can determine the left and right-hand paths along with the shortest path so that you can figure out which layout has the best chance of confounding visitors.
 

Input
Input to this problem will begin with a line containing a single integer n indicating the number of mazes. Each maze will consist of one line with a width, w, and height, h (3 <= w, h <= 40), followed by h lines of w characters each that represent the maze layout. Walls are represented by hash marks ('#'), empty space by periods ('.'), the start by an 'S' and the exit by an 'E'. 

Exactly one 'S' and one 'E' will be present in the maze, and they will always be located along one of the maze edges and never in a corner. The maze will be fully enclosed by walls ('#'), with the only openings being the 'S' and 'E'. The 'S' and 'E' will also be separated by at least one wall ('#'). 

You may assume that the maze exit is always reachable from the start point.
 

Output
For each maze in the input, output on a single line the number of (not necessarily unique) squares that a person would visit (including the 'S' and 'E') for (in order) the left, right, and shortest paths, separated by a single space each. Movement from one square to another is only allowed in the horizontal or vertical direction; movement along the diagonals is not allowed.
 

Sample Input
2
8 8
########
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S#E####
9 5
#########
#.#.#.#.#
S.......E
#.#.#.#.#
#########
 

Sample Output
37 5 5
17 17 9
 

Source
PKU
 

题目大意:这是一个走迷宫的问题,入口为S,出口为E。以输入输出来看问题:输入第一行表示案例数。第二行表示案例一的迷宫的行与列,余下的就是对迷宫构造的描述。以后的案例同上

输出 : 输出一行,第一个表示一直向左走(当然,左边没路再向前或右或后)走出迷宫用的时间(每走一格一分钟),第二个表示一直向右走所用的时间,最后一个表示走出迷宫能用的最少时间。   注意:都可以走出去,不用担心完不成的情况

#include<iostream>
using namespace std;
int w,h;            //行和列
int l,r,m;          //输出的三个结果
int si,sj,di,dj;    //表示入口和出口的坐标
char as[100][100];  
int bs[100][100];
int dx[4]={0,-1,0,1}; //四个方向的变化
int dy[4]={-1,0,1,0};
int judge1(int c)    //第一种(一直向左走)的方向选择
{
    if(c==1) return 0;
    if(c==2) return 1;
    if(c==3) return 2;
    return 3;
}
int judge2(int c)    //第二种和第三种的方向选择
{
    if(c==1) return 2;
    if(c==2) return 3;
    if(c==3) return 0;
    return 1;
}
void dfs(int x,int y,int kd,int c,int cnt)   //x,y表示当前位置,kd表示第几种情况,c来确定走的方向,cnt表示走的步数
{
    if(x<0 || y<0 || x>=h || x>=w || as[x][y]=='#')  //返回的条件
        return ;
    if(kd==1)
    {
        if((x==di)&&(y==dj))    //结束的条件
        {
            l=cnt;
            return ;
        }
        int T=0;
        c=judge1(c);   //走的方向的确定
        while( T<4)
        {
            int xx=x+dx[c];
            int yy=y+dy[c];
            if(xx<0||yy<0||xx>=h||yy>=w||as[xx][yy]=='#');  路径不通,继续换
            else break; 路径通了,走下去
            ++c;
            c%=4;
            T++;
        }
        dfs(x+dx[c],y+dy[c],kd,c,cnt+1);  继续后续的行进
    }
     if(kd==2)
    {
        if((x==di)&&(y==dj))
        {
            r=cnt;
            return ;
        }
        int T=0;
        c=judge2(c);
        while(T<4)
        {
            int xx=x+dx[c];
            int yy=y+dy[c];
            if(xx<0||yy<0||xx>=h||yy>=w||as[xx][yy]=='#');
            else break;
            --c;
            c=(c+4)%4;
            T++;
        }
        dfs(x+dx[c],y+dy[c],kd,c,cnt+1);
    }
    if(kd==3)
    {
        if(m<=cnt||bs[x][y]<=cnt)
        return;
        bs[x][y]=cnt;
        if((x==di)&&(y==dj))
        {
            m=cnt;
            return;
        }
        int T=0;
        as[x][y]='#';
        c=judge2(c);
        while(T<4)
        {
            dfs(x+dx[c],y+dy[c],kd,c,cnt+1);
            ++c;
            c%=4;
            T++;
        }
    }
    as[x][y]='.';
}
int main()
{
    int i,j,t;
    cin>>t;
    while(t--)
    {
        cin>>w>>h;
        l=r=0;
        for(i=0;i<h;i++)
        {
            cin>>as[i];
        }
        for(i=0;i<h;i++)
            for(j=0;j<w;j++)
            {
               if(as[i][j]=='S')
               {
                   si=i;
                   sj=j;
               }
               if(as[i][j]=='E')
               {
                   di=i;
                   dj=j;
               }
               bs[i][j]=10000;
            }
        dfs(si,sj,1,-1,1);
        dfs(si,sj,2,-1,1);
        m=l>r?r:l;
        dfs(si,sj,3,-1,1);
        cout<<l<<" "<<r<<" "<<m<<endl;
    }
}

 

 

 

 

 

posted on 2013-10-05 12:49  天梦Interact  阅读(330)  评论(0编辑  收藏  举报