台州学院ACM:2506 An escape

3506: An escape 分享至QQ空间 去爱问答提问或回答
时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte
总提交: 228            测试通过:75
描述
You are now in a maze. You mark all the blocks you've visited by '@', so when you see a wall '#' or a visited block '@' in front of you, you will make a right turn. Otherwise, that means you don't have a wall or a visited block in front, you'll go forward. When you reach the door 'D', congratulations!
####
#Y@#
##D#
####
Look at the maze above, you are now in 'Y', facing left, and seeing a wall in front of you. You turn right, a wall again; turn right again, visited block; turn right once again, still a wall. After three continuous turnings, you realize the rest time of your life will be making turnings.
输入
The first line is T(T<=20), then T cases follow.
Each case has two numbers n and m(4<=n,m <= 20), the boundary of the maze will always be '#', in the maze, there will be exactly one 'Y', one 'D'. Normal blocks are marked with '.'.
At first you are facing left.
输出
"YES" if you can go out of the maze(reach 'D'). "NO" otherwise.
样例输入
2
4 4
####
#.Y#
##D#
####
4 4
####
#.Y#
#D##
####

样例输出
NO
YES

解题思路:
每走到一个位置(当然这个位置不是终点),就先判断一下它的上下左右是不是全不可以走,如果是这样的话,则这个人直接GG,程序结束,它逃不出迷宫。有一个数dir代表方向,初始dir的值为1,代表朝向左,如果遇到墙,d要进行向右转,则dir++,因此如果dir%4=1,代表朝向左,如果dir%4==2,代表朝向上,如果dir%4=3,代表朝向右边,如果dir%4==0,则代表朝向下方,如果一个点有能走的地方,我们就让它当前的朝向走,如果走不了,就转弯,重复判断或转向,具体思路见代码。
#include<iostream>
#include<stdio.h>
#include<string.h>

using namespace std;

int m,n;///m列,n行
int sx,sy;///起点
int dir;///代表方向
char Map[25][25];///迷宫地图
int life(int x,int y)///用于判断某点(x,y)上下左右是否无路可走的函数
{
    if(Map[x-1][y]=='.'||Map[x-1][y]=='D')///该点的上方可走
        return 1;///返回1,代表有可以走的地方
    if(Map[x][y+1]=='.'||Map[x][y+1]=='D')///该点的右方可走
        return 1;///返回1,代表有可以走的地方
    if(Map[x+1][y]=='.'||Map[x+1][y]=='D')///该点的下方可走
        return 1;///返回1,代表有可以走的地方
    if(Map[x][y-1]=='.'||Map[x][y-1]=='D')///该点的左方可走
        return 1;///返回1,代表有可以走的地方
    return 0;///代表上下左右四个方向,全都不通,则逃不出迷宫
}
int live()///判断是否能活着出去的函数,如果可以返回1,不能返回0
{
    int tx,ty;
    tx = sx;
    ty = sy;
    while(life(tx,ty))///四周有可以走的地方,就让它走
    {
        Map[tx][ty] = '#';///走过的地方直接标记为'#',则以后这一点都不可走了
        if(dir%4 == 1)///代表朝向左方
        {
            int dx = tx;///横坐标减1
            int dy = ty-1;
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m)///不出届
            {
                if(Map[dx][dy]=='.'||Map[dx][dy]=='D')///这一点可以走
                {
                    if(Map[dx][dy]=='.')///可以走,更新tx,ty
                    {
                        tx = dx; ty = dy;
                    }
                    if(Map[dx][dy]=='D')///是终点,结束函数,返回1
                        return 1;
                }
                else  dir++;
            }
        }
        else if(dir%4==2)///代表方向朝上
        {
            int dx = tx-1;
            int dy = ty;
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m)
            {
                if(Map[dx][dy]=='.'||Map[dx][dy]=='D')
                {
                    if(Map[dx][dy]=='.')
                    {
                        tx = dx; ty = dy;
                    }
                    if(Map[dx][dy]=='D')
                        return 1;
                }
                else  dir++;
            }
        }
        else if(dir%4==3)///朝右边
        {
            int dx = tx;
            int dy = ty + 1;
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m)
            {
                if(Map[dx][dy]=='.'||Map[dx][dy]=='D')
                {
                    if(Map[dx][dy]=='.')
                    {
                        tx = dx; ty = dy;
                    }
                    if(Map[dx][dy]=='D')
                        return 1;
                }
                else  dir++;
            }
        }
        else if(dir%4==0)///代表朝下边
        {
            int dx = tx + 1;
            int dy = ty;
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m)
            {
                if(Map[dx][dy]=='.'||Map[dx][dy]=='D')
                {
                    if(Map[dx][dy]=='.')
                    {
                        tx = dx; ty = dy;
                    }
                    if(Map[dx][dy]=='D')
                        return 1;
                }
                else  dir++;
            }
        }
    }
    return 0;
}
int main()
{
    int T,i,j;///T组测试数据
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);///假如为行,列顺序
        dir = 1;///代表初始朝向左边
        memset(Map,'#',sizeof(Map));
        for(i = 1; i <= n; i++)
            for(j = 1; j <=m; j++)
            {
                scanf(" %c",&Map[i][j]);
                if(Map[i][j] == 'Y')
                {
                    sx = i;
                    sy = j;
                }
            }
        int ans = live();
        if(ans == 1)
            printf("YES\n");
        else
            printf("NO\n");
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值