Low Coder的博客

你必须非常努力,才能看起来毫不费力。

EOJ3268 神奇怪兽在哪里

3268. 神奇怪兽在哪里

Time limit per test: 2.0 seconds

Memory limit: 256 megabytes

熊猫先生最近在玩一款单机游戏。

在游戏中,会有一张 n 行 m 列的地图(如样例中所示)。用 . 表示空地,用 * 表示怪兽,用 P 表示熊猫先生现在所在的位置。怪兽只有一个,所以由 * 组成的块一定是一个上下左右四连通块。游戏的规则是:熊猫先生要把怪兽「包住」,并且回到现在所在的位置,才能把怪兽消灭掉。

「包住」的含义是:走过的路径可以将怪兽封闭起来。只能在空地上行走。走过的路径可以相交,可以重叠,可以重复走,只要围住就好了。

由于这是一款在命令行下运行的复古单机游戏,熊猫先生只能按上下左右四个键,即他只能向上下左右四个方向移动。你能找到一种消灭怪兽的方法吗?

Input

输入包含多个测试文件,每个测试文件是单组测试数据。

第一行两个整数 n,m (1n,m100)。对于 30% 的数据,满足:1n,m20

接下来 n 行,每行一个长度为 m 的字符串,表示地图。

. 表示空地,* 表示怪兽,P 表示熊猫先生现在所在的位置。输入保证熊猫先生不会出现在「怪兽里面」。

Output

输出一行,一个字符串,表示要消灭怪兽所要执行的操作序列:

  • 向上走用 U 表示;
  • 向下走用 D 表示;
  • 向左走用 L 表示;
  • 向右走用 R 表示。

输入保证有解。输出任意一解即可。

Examples

input
6 10
..........
...***..P.
..**......
..*****...
.....***..
..........
output
DDDDLLLLLLULUUUURRRRRRDR

Note

样例给出的答案路径是:

.PPPPPPP..
.P.***.PP.
.P**....P.
.P*****.P.
.PP..***P.
..PPPPPPP.

答案可以有多种情形,围出下面的形式也是可以的:

.PPPPPPP..
.P.***.PP.
.P**PPPPP.
.P*****.P.
.PP..***P.
..PPPPPPP.

注意在这种方案中,走过的路发生了重叠。

你甚至还可以绕多圈,以至于变成了这样:

PPPPPPPPPP
PPP***PPPP
PP**PPPPPP
PP*****PPP
PPPPP***PP
PPPPPPPPPP

只要你的输出序列能让你回到原点,这种情况也是正确的。

中文题意不解释。

一开始看到这道题觉得常规搜索题,毕竟最近这一周一直在肝搜索。

但是一开始还是无从下手,不知道怎么搜。

后来想了一下,只需从起点出发,搜到任意的一个角落(把这个路径记录下来,然后绕一圈再回到原处就可以了。

所以是dfs,但这里一开始犯了一个错误。

就是dfs并不是一定搜的就是正确的。所以在回溯的时候需要删除末尾元素(vector真是好用。

绕过了这几个坑就没什么问题了。

dfs是要比bfs难一点啊...

//#include <bits/stdc++.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <queue>
#include <stack>
#include <algorithm>
#define __max(a,b)  (((a) > (b)) ? (a) : (b))
#define __min(a,b)  (((a) < (b)) ? (a) : (b))
using namespace std;
const int maxn = 500;
const int N = 2e3+10;
bool used[N][maxn];
bool Prime[maxn];
char maze[maxn][maxn];
typedef pair<int,int> P;
int dx[] = {-1,0,0,1,0,0};
int dy[] = {0,-1,1,0,0,0};
int dz[] = {0,0,0,0,-1,1};
typedef long long ll;
int t,n,m;//t记录到达四个角所需要的步数
int flag;
const char dire[5] = "ULRD";//映射方向
vector<int> ans;
void solve(int mode)//填充绕一圈的路径
{
    switch (mode) {
        case 0:
            for(int i = 0; i < n-1; i++)
                ans.push_back(0);
            break;
        case 1:
            for(int i = 0; i < m-1; i++)
                ans.push_back(1);
            break;
        case 2:
            for(int i = 0; i < m-1; i++)
                ans.push_back(2);
            break;
        case 3:
            for(int i = 0; i < n-1; i++)
                ans.push_back(3);
            break;
        default:
            break;
    }
}
void dfs(int x, int y){
    if(flag) return;
    used[x][y] = 1;
    if(x == 0 && y == 0){
        solve(3);solve(2);solve(0);solve(1);
        flag = 1;return;
        }
    if(x == 0 && y == m-1){
        solve(3);solve(1);solve(0);solve(2);
        flag = 1;return;
    }
    if(x == n-1 && y == 0){
        solve(0);solve(2);solve(3);solve(1);
        flag = 1;return;
    }
    if(x == n-1 && y == m-1){
        solve(1);solve(0);solve(2);solve(3);
        flag = 1;return;
    }
    for(int i = 0; i < 4; i++)
    {
        int px = dx[i] + x, py = dy[i] +y;
        if(maze[px][py] != '*' && px >= 0 && px < n && py >=0 && py < m && used[px][py] == 0)
        {
            t++;//到达四个角所需步数
            ans.push_back(i);
            used[px][py] = 1;
            dfs(px, py);
            if(flag) return;
            ans.pop_back();//回溯时如果不是搜到了就要删除末尾元素
            t--;//路径数量要减去1
        }
    }
}
int main()
{
    std::ios::sync_with_stdio(false);
    //freopen("/Users/vector/Desktop/input.txt", "r", stdin);
    cin>>n>>m;
    {
        memset(used,0,sizeof(used));
        for(int i = 0; i < n; i++)
            cin>>maze[i];
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
            {
                if(maze[i][j] == 'P')
                {dfs(i,j);break;}
            }
        for(int i = t-1; i >= 0; i--)
            ans.push_back(3-ans[i]);//反方向的路径加到末尾
        for(int i = 0; i < ans.size(); i++)
            cout<<dire[ans[i]];
        cout<<endl;
    }
    return 0;

}


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_37158899/article/details/79323818
个人分类: DFS
想对作者说点什么? 我来说一句

unity3D仿口袋妖怪游戏源码

2018年01月26日 215.35MB 下载

【转】口袋妖怪的一些小图标

2014年01月30日 49KB 下载

没有更多推荐了,返回首页

不良信息举报

EOJ3268 神奇怪兽在哪里

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭