题目链接:http://codeforces.com/gym/101755/problem/H

题目分析:先bfs一遍怪兽可以到达的点,再bfs人可以走的地方看可不可以到达终点;

     很显然读到  2<=n*m<=200000 时,就不可以用二维数组存图了,不过据说因为数据比较水,可以用vector存图;

vector存图AC代码:

 /* */
# include <iostream>
# include <stdio.h>
# include <string.h>
# include <string>
# include <cmath>
# include <climits>
# include <cctype>
# include <ctime>
# include <algorithm>
# include <functional>
# include <bitset>
# include <set>
# include <map>
# include <deque>
# include <queue>
# include <stack>
# include <vector>
using namespace std; const int maxn=2e5+;
vector<char>mp[maxn];
vector<int>dis[maxn];
vector<int>vis[maxn];
int n, m; struct node
{
int x, y;
int step;
}cur, after; int dir[][]={{, }, {, -}, {, }, {-, }};
int sx, sy, fx, fy; int check(int x, int y)
{
if( x>= && x<n && y>= && y<m )
return ;
return ;
} void bfs1(int d)
{
queue<node>q;
int i, j;
for( i=; i<n; i++ )
{
for( j=; j<m; j++ )
{
if( mp[i][j]=='M' )
{
cur.x = i;
cur.y = j;
cur.step = ;
q.push(cur);
dis[i][j] = ;
}
}
} while( !q.empty() )
{
cur = q.front();
q.pop();
for(int i=; i<; i++ )
{
after.x = cur.x+dir[i][];
after.y = cur.y+dir[i][];
after.step = cur.step + ; if( check(after.x, after.y) )
{
if( !dis[after.x][after.y] && after.step<=d )
{
dis[after.x][after.y] = ;
q.push(after);
}
}
}
}
} void bfs2(int x, int y)
{
cur.x = x;
cur.y = y;
cur.step = ;
queue<node>q;
q.push(cur);
vis[x][y] = ;
if( dis[x][y] )
{
printf("-1\n");
return ;
}
while( !q.empty() )
{
cur = q.front();
q.pop();
if( mp[cur.x][cur.y]=='F' )
{
printf("%d\n", cur.step);
return ;
}
for(int i=; i<; i++ )
{
after.x = cur.x + dir[i][];
after.y = cur.y + dir[i][];
after.step = cur.step + ;
if( check(after.x, after.y) )
{
if( !dis[after.x][after.y] && !vis[after.x][after.y])
{
vis[after.x][after.y] = ;
q.push(after);
}
}
}
}
printf("-1\n");
return ;
}
int main()
{
int d, i, j;
cin>>n>>m>>d;
char s; for(i=; i<n; i++)
{
mp[i].clear();
vis[i].clear();
dis[i].clear();
} for(i=; i<n; i++ )
{
for(j=; j<m; j++ )
{
cin>>s;
mp[i].push_back(s);
dis[i].push_back();
vis[i].push_back();
}
}
bfs1(d); for(i=; i<n; i++ )
{
for( j=; j<m; j++ )
{
if( mp[i][j]=='F' )
{
fx = i;
fy = j;
}
if( mp[i][j]=='S' )
{
sx = i;
sy = j;
}
}
} if( dis[fx][fy] )
{
printf("-1\n");
}
else
{
bfs2(sx, sy);
}
return ;
}

这道题也让我知道了可以用一位数组存图:

详细的见代码注释:

AC代码:

 /* */
# include <iostream>
# include <stdio.h>
# include <string.h>
# include <algorithm>
# include <cctype>
# include <ctime>
# include <functional>
# include <cmath>
# include <bitset>
# include <deque>
# include <queue>
# include <stack>
# include <vector>
# include <set>
# include <map>
# include <climits>
using namespace std; typedef long long LL;
const int maxn=1e6+;
int n, m, t;
int a[maxn], d;
char str[maxn];
bool vis[maxn];///标记是否已经访问过
int dis[maxn];///记录步数
int dd[maxn];///dd[]为0,说明怪兽到不了,dd不为0说明怪兽可以到此处
int cnt, fx, fy, sx, sy;
int dir[][]={{, }, {, -}, {-, }, {, }};
struct node
{
int x;
int y;
}g[maxn], cur, after; bool check(int a, int b)
{
if( a>= && b>= && a<=n && b<=m && !dd[a*m+b] )
return true;
return false;
} void bfs()
{
queue<node>q;
cur.x = sx;
cur.y = sy;
vis[cur.x*m+cur.y] = ;
q.push(cur); while( !q.empty())
{
cur = q.front();
q.pop();
for(int i=; i<; i++ )
{
int xx = cur.x + dir[i][];
int yy = cur.y + dir[i][]; if( check(xx, yy) && !vis[xx*m+yy])
{
dis[xx*m+yy] = dis[cur.x*m+cur.y]+;
vis[xx*m+yy] = ;
after.x = xx;
after.y = yy;
q.push(after);
}
}
}
return ;
} void bfss()///广搜怪兽可以到达的地方
{
queue<node>q;
for(int i=; i<cnt; i++ )
q.push(g[i]); while( !q.empty() )
{
cur=q.front();
q.pop(); if( dd[cur.x*m+cur.y]== )
continue; for(int i=; i<; i++ )
{
int xx = cur.x + dir[i][];
int yy = cur.y + dir[i][];
if( check(xx, yy) )
{
after.x = xx;
after.y = yy;
dd[xx*m+yy] = dd[cur.x*m+cur.y]-;
q.push(after);
}
}
}
return ;
} int main()
{
while( ~ scanf("%d %d %d", &n, &m, &d) )
{
getchar();
for(int i=; i<=n; i++ )
scanf("%s", &str[i*m+]);///一维数组存图 memset(vis, false, sizeof(vis));
memset(dd, , sizeof(dd));
memset(dis, , sizeof(dis)); for(int i=; i<=n; i++ )
{
for(int j=; j<=m; j++ )
{
if( str[i*m+j]=='S' )
{
sx = i;
sy = j;
} else if( str[i*m+j]=='F' )
{
fx = i;
fy = j;
} else if( str[i*m+j]=='M' )
{
dd[i*m+j] = d+;
cur.x = i;
cur.y = j;
g[cnt++] = cur;
}
}
} bfss();
if( dd[sx*m+sy] || dd[fx*m+fy] )
{
printf("-1\n");
}
else
{
bfs();
if( !vis[fx*m+fy] )
printf("-1\n");
else
printf("%d\n", dis[fx*m+fy]);
}
}
return ;
}

Safe Path(bfs+一维数组存图)的更多相关文章

  1. Codeforces gym101755H Safe Path(bfs)

    题意: 给以一个网格图,有起点终点和一些怪兽,可以上下左右走,不能走到距离怪兽曼哈顿距离为d以内的地方,问到终点最短路径 n*m<=2e5,d<=2e5 思路: 因为n*m的范围,不能直接 ...

  2. POJ 1985.Cow Marathon-树的直径-树的直径模板(BFS、DFS(vector存图)、DFS(前向星存图))

    Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 7536   Accepted: 3559 Case ...

  3. QDUOJ 生化危机 邻接表存图+BFS

    生化危机 发布时间: 2015年10月10日 18:05   时间限制: 1000ms   内存限制: 256M 描述 X博士想造福人类, 研发一种可以再生肢体的药物, 可是很不幸......研究失败 ...

  4. 学JAVA第十天,一维数组及二维数组的使用。

    今天老师讲了JAVA数组,之前学C#的时候就学过一维数组,至于二维数组当时只是粗略普及了一下. 现在想学JAVA又学到了数组,但是这次不同,注重讲二维数组,因为老师知道我们都了解一维数组了. 所以现在 ...

  5. java基础5 (一维)数组和二维数组

    本文知识点(目录): 一维数组(一维数组的概念.优点.格式.定义.初始化.遍历.常见异常.内存分析以及常见操作(找最大值.选择排序.冒泡排序等等))    二维数组(二维数组的遍历.排序.查找.定义. ...

  6. B - Cow Marathon DFS+vector存图

    After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exerc ...

  7. Treasure Island DFS +存图

    All of us love treasures, right? That's why young Vasya is heading for a Treasure Island. Treasure I ...

  8. js cookie 数组 存读

    自己研究了一下. "Cookie里面只能放String 类型" 所以只能将arr的数据按照自己的约定转成string格式存进cookie. 这里提示一下cookie是存在本地浏览器 ...

  9. C# 数组、一维数组、二维数组、多维数组、锯齿数组

    C#  数组.一维数组.二维数组.多维数组.锯齿数组 一.数组: 如果需要使用同一类型的对象,就可以使用数组,数组是一种数据结构,它可以包含同一类型的多个元素.它的长度是固定的,如长度未知的情况下,请 ...

随机推荐

  1. Microsoft.AspNet.Identity 自定义使用现有的表—登录实现,aspnet.identity

    Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现.Microsoft.AspNet.Identity.EntityFrame ...

  2. Java Web 深入分析(11) JVM(1)

    前言 Java启动后作为一个进程运行在操作系统中,该进程要分配的内存有以下几个: 1.Java堆: 存储java内存区域,堆大小是在jvm启动时就像操作系统申请完成,其中 -Xmx和-Xms 分别表示 ...

  3. Qt Table Widget常用操作

    一.鼠标悬浮在item上 显示提示信息 1.在构造函数开启table Widget控件的鼠标捕获功能 // 开启鼠标捕获功能(实现table widget的悬浮功能) ui.tableWidget-& ...

  4. c#使用正则表达式处理字符串

    正则表达式可以灵活而高效的处理文本,可以通过匹配快速分析大量的文本找到特定的字符串. 可以验证字符串是否符合某种预定义的格式,可以提取,编辑,替换或删除文本子字符串. 现在如下特定的字符串: stri ...

  5. iview 标题内边距过大; 调整iview 单元格内边距、行高;

    1css代码: /*调整table cell间隔和行高*/ .ivu-table-cell { padding-left: 1px; padding-right: 1px; } .ivu-table- ...

  6. Python学习日记(六) 浅深copy

    浅深copy即完全复制一份和部分复制一份 浅深copy在列表数据量较大时不建议使用,比较消耗内存资源 1.赋值运算 l1 = [1,'s',[1,2,3]] l2 = l1 print(id(l1), ...

  7. RobotFramework+Eclipse的安装和配置(一)

    最近想学robotframwork来做自动化,那立马就来开始上手 想动手,起码要先下载工具,工具及框架 工具介绍 Robotframework:一款自动化测试框架. Eclipse:一款编辑工具,可以 ...

  8. Centos7启动流程及systemd中Nginx启动配置

    Centos7启动流程: 1.post(Power-On-Self-Test) 加电自检 主要实现的功能是检测各个外围硬件设备是否存在而且能够正常运行起来,实现这一自检功能的是固化在主板上的ROM(主 ...

  9. [lambda] newbies of haskell

    site: https://www.haskell.org/ tutorial: http://learnyouahaskell.com/chapters 只言片语 Recursion is impo ...

  10. java写入内容到本地文件 -读取文件内容

    /** 日志记录 * @author sys * @param content 要写入的类容 * @param path 目标路径 c:/log/ * @param filename 文件名 log. ...