搜索加标记

原创 2018年04月15日 20:22:00

Gym - 101755H

题目网址:http://codeforces.com/gym/101755/problem/H

H. Safe Path
time limit per test
2.0 s
memory limit per test
256 MB
input
standard input
output
standard output

You play a new RPG. The world map in it is represented by a grid of n × m cells. Any playing character staying in some cell can move from this cell in four directions — to the cells to the left, right, forward and back, but not leaving the world map.

Monsters live in some cells. If at some moment of time you are in the cell which is reachable by some monster in d steps or less, he immediately runs to you and kills you.

You have to get alive from one cell of game field to another. Determine whether it is possible and if yes, find the minimal number of steps required to do it.

Input

The first line contains three non-negative integers nm and d (2 ≤ n·m ≤ 200000, 0 ≤ d ≤ 200000) — the size of the map and the maximal distance at which monsters are dangerous.

Each of the next n lines contains m characters. These characters can be equal to «.», «M», «S» and «F», which denote empty cell, cell with monster, start cell and finish cell, correspondingly. Start and finish cells are empty and are presented in the input exactly once.

Output

If it is possible to get alive from start cell to finish cell, output minimal number of steps required to do it. Otherwise, output «-1».

Examples
input
Copy
5 7 1
S.M...M
.......
.......
M...M..
......F
output
Copy
12
input
Copy
7 6 2
S.....
...M..
......
.....M
......
M.....
.....F
output
Copy
11
input

Copy
7 6 2
S.....
...M..
......
......
.....M
M.....
.....F
output
Copy
-1
input
Copy
4 4 2
M...
.S..
....
...F
output
Copy
-1
Note

Please note that monsters can run and kill you on start cell and on finish cell as well.


题的大概意思是:给你一个图,然后M点上是怪兽,这个M点的怪兽可以攻击到d距离的人,然后求从S点到F点最短的距离(不能被怪兽攻击到),你和怪兽只能上下左右走,不可以斜着走(大概意思,当时没有读题,看的样例猜的题意)

省赛积分赛做到的题,当时一看,因为看到了n*m的范围,就想到了开一维(因为上次浙大校赛也做过一个,当时也用到了一维)。比赛的时候,写了40.50分钟吧,因为一些小的处理,没有处理好,而且自己心里又着急,就放弃了。

刚刚吃完饭回来,不到20分钟,改了一下就过了,回头想想,当时是真的菜。


大概思路:因为有n*m的范围,直接把数组开成一维,然后字符串和标记数组的下标都从1开始,接着去记录每个出现M的点以及起点和终点的位置。然后我用了一个dd数组来表示M这个怪兽最多可以蔓延到的距离,So,bfs出所有M的点,然后把出现到的范围标记,这儿用了一个处理,就是先把M的位置设为d+1,然后每次蔓延一个距离让它减一,直到0的时候就停止蔓延。

接着在一个bfs去搜起点和终点,然后dis标记距离,最基本的bfs就可以了,只能走dd为0的地方,因为如果大于0,M的怪兽就会攻击你。

代码如下:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int Maxn = 1e6 + 100;
int n,m,t;
int a[Maxn],d;
char str[Maxn];
bool vis[Maxn];
int dis[Maxn];
int dd[Maxn];
int cnt,enx,eny,stx,sty;
int xx[4] = {1,-1,0,0};
int yy[4] = {0,0,-1,1};
struct node {
    int x,y;
} g[Maxn];
bool check(int a,int b) {
    if(a >= 1 && b >= 1 && a <= n && b <= m && dd[a * m + b] == 0)
        return true;
    return false;
}
void bfss() {
    queue<node>q;
    for(int i = 0; i < cnt; i++)
        q.push(g[i]);
    while(!q.empty()) {
        node b = q.front();
        q.pop();
        if(dd[b.x * m + b.y] == 0)
            continue;
        for(int i=0; i < 4; i++) {
            int X = b.x + xx[i];
            int Y = b.y + yy[i];
            if(check(X,Y)) {
                node c;
                c.x = X;
                c.y = Y;
                dd[X * m + Y] = dd[b.x * m + b.y] - 1;
                if(dd[X * m + Y] != 0)
                    q.push(c);
            }
        }
    }
    return ;
}

void bfs() {
    queue<node>q;
    node a,b,c;
    a.x = stx;
    a.y = sty;
    vis[stx * m + sty] = 1;
    q.push(a);
    while(!q.empty()) {
        b = q.front();
        q.pop();
        for(int i = 0; i < 4; i++) {
            int X = b.x + xx[i];
            int Y = b.y + yy[i];
            if(check(X,Y) && !vis[X * m + Y]) {
                dis[X * m + Y] = dis[b.x * m + b.y] + 1;
                vis[X * m + Y] = 1;
                c.x = X;
                c.y = Y;
                q.push(c);
            }
        }

    }
}
int main() {
    while(~scanf("%d%d%d",&n,&m,&d)) {
        getchar();
        for(int i = 1; i <= n; i++)
            scanf("%s",&str[i * m + 1]);
        memset(vis,0,sizeof(vis));
        memset(dd,0,sizeof(dd));
        memset(dis,0,sizeof(dis));
        for(int i = 1; i <= n; i++)  {
            for(int j = 1; j <= m; j++) {
                if(str[i * m + j] == 'S')
                    stx = i,sty = j;
                else if(str[i * m + j] == 'F')
                    enx = i,eny = j;
                else if(str[i * m + j] == 'M') {
                    node a;
                    dd[i * m + j] = d + 1;
                    a.x = i;
                    a.y = j;
                    g[cnt++] = a;
                }
            }
        }
        bfss();
        if(dd[stx * m + sty] > 0 || dd[enx * m + eny] > 0) {
            printf("-1\n");
            continue;
        }
        bfs();
        if(dis[enx * m + eny] == 0) {
            printf("-1\n");
        } else printf("%d\n",dis[enx * m + eny]);
    }
    return 0;
}



版权声明:欢迎大家评论和指出错误,互相交流,如有转载,请指明出处 https://blog.csdn.net/qq_38185591/article/details/79952703

GIS(一)——在js版搜索地图上添加Marker标记

由于我们做的是有关于旅游方面的项目,所以涉及到了地图功能。我接到的其中一个任务就是,在地图上显示指定的几个景点,并在地图上加上标记。        我们项目用的是搜狗地图,使用的是js版本。大家有兴趣...
  • xiaoxian8023
  • xiaoxian8023
  • 2014-08-26 22:48:08
  • 6973

android学习之基于百度地图的地点检索和标记

在现在的生活之中,地图越来越重要,作为一个普通的程序员,我们不可能自己去编写一个地图,所以,这篇文章写的是关于如何利用百度的第三方框架来写自己的程序, 首先我们需要成为百度开发者,然后下载相关的SD...
  • justperseve
  • justperseve
  • 2016-05-10 19:34:03
  • 2970

Eclipse里同一变量显示行标记

在Eclipse环境下,打开一个类。如果选中一个变量,往往,只要其他行里也用到这个变量,就会在这一行的右侧边框处,显示一个标记。使用起来非常方便。要是不显示了,就比较麻烦了。怎么才能调出来呢,这些标记...
  • maoxin604
  • maoxin604
  • 2013-12-10 09:18:51
  • 1704

vi中怎么取消 查找 后的着色标记

1.办法1 :noh :set nohls 2.办法2 modify the file of ~/.exrc , add new line of  ...
  • hittata
  • hittata
  • 2013-01-15 14:40:42
  • 3944

1种基于用户标记的搜索结果排序算法.pdf

  • 2011年07月26日 11:39
  • 638KB
  • 下载

线段树 -- 区间修改 【下放懒人标记】

//分为区间覆盖,区间加或减. 这里只写一种区间覆盖(其他的照着改一下就可以了). 如果都有那就要是双标记, 下一篇讲 . 模板题 板子: const int maxn = 1e5+5; ...
  • Anxdada
  • Anxdada
  • 2017-07-26 15:50:24
  • 281

gc

地球人都知道,Java有个东西叫垃圾收集器,它让创建的对象不需要像c/cpp那样delete、free掉,你能不能谈谈,GC是在什么时候,对什么东西,做了什么事情? 一.回答:什么时候? 1.系统...
  • weixin_35684059
  • weixin_35684059
  • 2016-08-08 16:15:29
  • 177

Google地图.net代码

  • 2010年09月09日 11:21
  • 5KB
  • 下载

MATLAB图像中添加标记

指定坐标添加标记: text(x,y,str) 手动指定位置添加标记: gtext(str) 横纵坐标 xlabel('')%横 ylabel('')%纵 tittl...
  • cckit
  • cckit
  • 2014-11-12 16:36:22
  • 798

程序员,标记思想你要会。

放两天假,昨天第一次去珠海的图书馆,然后又去体育中心。在宿舍闲的蛋疼。今天下午跑完4000米。跑完后感觉一个字爽。哈哈。回寝室的时候脑海中突然有个一闪而过的想法,发现很多的业务都要用到一个思想那就是标...
  • u010916821
  • u010916821
  • 2013-11-23 21:22:05
  • 725
收藏助手
不良信息举报
您举报文章:搜索加标记
举报原因:
原因补充:

(最多只允许输入30个字)