追踪ws的怪蜀黍(DFS)

追踪WS的怪蜀黍

美丽的河海大学校园里惊现一只ws的怪蜀黍,搞得校园里的女同胞们人心惶惶。河海大学男同胞们个个义愤填膺,他们打算团结起来捕捉这只ws怪蜀黎,把它送到相关部门处理。所以男同胞们成立了一个“BeatWS”团队,决定展开激烈的搜捕,捕捉这只怪蜀黎。然而怪蜀黎也是相当狡猾的,它提高了警惕,并尽量地躲开男同胞们的视线,妄想逃之夭夭。

假设河海大学是一个M*N的矩形点阵(2<=m,n<=20)。

怪蜀黎是在其中的一个点,用大写字母W表示。

男同胞分布在图中的某些点,用大写字母S表示(S的数目>=0)。

道路用.表示。

假设人的视线范围是当前位置的上下左右一格的距离(即以当前位置为中心点的十字)。

问怪蜀黎能否在不被看到的情况下,走到校园的出口E,当然,如果ws怪蜀黎在E处被发现,也算怪蜀黎逃脱成功。

题目保证一定存在W和E.


举例:

..E

W.S

...

W走的过程中,S看不到W,怪蜀黎可以成功逃走。


S.E.

..S.

W...

怪蜀黎不管怎么走都会被发现的。

题目描述:
就是一道简单的DFS,但是却被卡了很久。里面有很多之前没有注意到的地方。
首先,对于一个点来说,他可能有多种方式经过这路。对于可行解的题目,每次到这个点的状态是一样的(未找到解),所以不需要继续在深入进去。而在找最短路径或者最优路径的时候,每次到这里的状态可能是不一样的,所以需要继续进入更新,但是如果一直深入却很有可能超时,所以一般在求解最优路径时往往用广搜放入队列来解决。
其次,在找不到bug的时候输出中间状态是一种很好的方法!
代码实现:
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#define MAX 22

using namespace std;

int M,N;
int flag;
int d[4][2]={1,0, -1,0, 0,1, 0,-1};
char maze[MAX][MAX];
void DFS(int x,int y);
bool if_catch(int x,int y);
int main()
{
    cin>>M>>N;
    int sx,sy;
    int ex,ey;
    flag = false;
    for( int i = 0; i < M; i++ )
    {
        cin>>maze[i];
        getchar();
    }
    for( int i = 0; i < M; i++ )
    {
        for( int j = 0; j < N; j++ )
        {
            if( maze[i][j] == 'E' )
            {
                ex = i;
                ey = j;
            }
            else if( maze[i][j] == 'W' )
            {
                sx = i;
                sy = j;
            }
            else if( maze[i][j] == 'S' )
            {
                for( int s = 0; s < 4; s++ )
                {
                    int nx = i+d[s][0];
                    int ny = j+d[s][1];
                    if( nx >= 0 && nx < M && ny >= 0 && ny < N && maze[nx][ny] != 'E' && maze[nx][ny] != 'W' && maze[nx][ny] != 'S')
                        maze[nx][ny] = 's';
                }
            }
        }
    }
//    cout<<endl;
//    for( int i = 0; i < M; i++ )
//    {
//        cout<<maze[i]<<endl;
//    }
    if( if_catch( sx,sy ) )
    {
        cout<<"No"<<endl;
        return 0;
    }
    DFS(sx,sy);
//    cout<<endl;
//    for( int i = 0; i < M; i++ )
//    {
//        cout<<maze[i]<<endl;
//    }
    if( flag )
        cout<<"Yes"<<endl;
    else
        cout<<"No"<<endl;
    return 0;
}

void DFS( int x, int y )
{
    if( maze[x][y] == 'E' || flag )
    {
        flag = true;
        return ;
    }
    maze[x][y] = 'W';
    for( int i = 0; i < 4; i++ )
    {
        int nx = x+d[i][0];
        int ny = y+d[i][1];
        if( nx >= 0 && nx < M && ny >= 0 && ny < N && (maze[nx][ny] == '.' || maze[nx][ny] == 'E') )
        {
            DFS(nx,ny);
            //maze[x][y] = '.';
        }
        if( flag )
            break;
    }
    return ;
}

bool if_catch(int x,int y)
{
    for( int i = 0; i < 4; i++ )
    {
        int nx = x+d[i][0];
        int ny = y+d[i][1];
        //
        if( maze[nx][ny] == 'S' )
            return true;
    }
    return false;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值