Find a way

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 25379    Accepted Submission(s): 8243

Problem Description
Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki.
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest.
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes.
 



Input
The input contains multiple test cases.
Each test case include, first two integers n, m. (2<=n,m<=200).
Next n lines, each line included m character.
‘Y’ express yifenfei initial position.
‘M’    express Merceki initial position.
‘#’ forbid road;
‘.’ Road.
‘@’ KCF
 



Output
For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.
 
Sample Input
4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#
 



Sample Output
66
88
66
 



Author
yifenfei
 



Source
 



Recommend
yifenfei   |   We have carefully selected several similar problems for you:  1254 1728 1072 1175 2579 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这道题因为有两个人要走
所以此处对两个人
每一个KFC
进行分别的搜索
搜索到一个KFC对应的两个值相加最小
就直接输出
但是要注意一个问题
先上我的TLE代码
 //Author:LanceYu
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<fstream>
#include<iosfwd>
#include<sstream>
#include<fstream>
#include<cwchar>
#include<iomanip>
#include<ostream>
#include<vector>
#include<cstdlib>
#include<queue>
#include<set>
#include<ctime>
#include<algorithm>
#include<complex>
#include<cmath>
#include<valarray>
#include<bitset>
#include<iterator>
#define ll long long
using namespace std;
const double clf=1e-;
//const double e=2.718281828;
const double PI=3.141592653589793;
const int MMAX=;
//priority_queue<int>p;
//priority_queue<int,vector<int>,greater<int> >pq;
struct node
{
int x,y,step;
};
queue<node> q;
int n,k,vis[][];
char map[][];
int dir[][]={{,},{-,},{,-},{,}};//四个方向
int bfs(int a,int b,int r1,int r2)
{
while(!q.empty())
q.pop();
int i;
q.push(node{a,b,});
vis[a][b]=;
while(!q.empty())
{
node t=q.front();
q.pop();
if(t.x==r1&&t.y==r2)
return t.step;
for(i=;i<;i++)
{
int dx=t.x+dir[i][];
int dy=t.y+dir[i][];
if(dx>=&&dy>=&&dx<n&&dy<k&&!vis[dx][dy]&&map[dx][dy]!='#')//正常搜索
{
vis[dx][dy]=;
q.push(node{dx,dy,t.step+});
}
}
}
return MMAX;//如果搜不到就返回一个不能使ans改变的值
}
int main()
{
int a1,b1,a2,b2,r1[],r2[];
while(scanf("%d%d",&n,&k)!=EOF)
{
int t=,ans=MMAX,temp=;
for(int i=;i<n;i++)
{
scanf("%s",&map[i]);
for(int j=;j<k;j++)
{
if(map[i][j]=='Y')
{
a1=i;
b1=j;
}
if(map[i][j]=='M')//求出两个点的位置作为起点
{
a2=i;
b2=j;
}
if(map[i][j]=='@')//如果是KFC放到数组里面
{
r1[t]=i;
r2[t]=j;
t++;
}
}
}
for(int i=;i<t;i++)//寻找能到的KFC的最小值
{
temp=;
memset(vis,,sizeof(vis));
temp+=bfs(a1,b1,r1[i],r2[i]);
memset(vis,,sizeof(vis));
temp+=bfs(a2,b2,r1[i],r2[i]);
ans=min(ans,temp);
}
printf("%d\n",ans*);
}
return ;
}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

乍一看这个代码似乎还很有道理

然而

但是为什么会T呢

原因其实很简单

就是因为bfs算法时间复杂度较高

如果多次进行bfs的话

铁定超时

此处一个KFC就进行一次搜索

导致超时

于是笔者想出了一个较为不错的方法

只进行一次bfs

记录下所能到达的位置所需的步数

这样只有两次深搜即可

但是这里要注意一个小小的bug

就是KFC可能到不了

笔者因为这个WA了几次的

下面附上我精确注释

谁都能看懂的代码

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 //Author:LanceYu
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<fstream>
#include<iosfwd>
#include<sstream>
#include<fstream>
#include<cwchar>
#include<iomanip>
#include<ostream>
#include<vector>
#include<cstdlib>
#include<queue>
#include<set>
#include<ctime>
#include<algorithm>
#include<complex>
#include<cmath>
#include<valarray>
#include<bitset>
#include<iterator>
#define ll long long
using namespace std;
const double clf=1e-;
//const double e=2.718281828;
const double PI=3.141592653589793;
const int MMAX=;
//priority_queue<int>p;
//priority_queue<int,vector<int>,greater<int> >pq;
struct node
{
int x,y;
}; int n,k,vis[][];
char map[][];
int dir[][]={{,},{-,},{,-},{,}};//四个方向
void bfs(int a,int b,int step[][])//暴力枚举能到的地方各点的步数
{
int i;
queue<node> q;
q.push(node{a,b});
vis[a][b]=;
while(!q.empty())
{
node t=q.front();
q.pop();
for(i=;i<;i++)
{
int dx=t.x+dir[i][];
int dy=t.y+dir[i][];
if(dx>=&&dy>=&&dx<n&&dy<k&&!vis[dx][dy]&&map[dx][dy]!='#'&&!vis[dx][dy])//基本搜索
{
vis[dx][dy]=;
step[dx][dy]=step[t.x][t.y]+;
q.push(node{dx,dy});
}
}
}
}
int main()
{
int a1,b1,a2,b2,step1[][],step2[][];
while(scanf("%d%d",&n,&k)!=EOF)
{
memset(step1,,sizeof(step1));
memset(step2,,sizeof(step2));
int t=,ans=MMAX;
for(int i=;i<n;i++)
{
scanf("%s",map[i]);
for(int j=;j<k;j++)
{
if(map[i][j]=='Y')
{
a1=i;
b1=j;
}
if(map[i][j]=='M')//把两个点记录下来
{
a2=i;
b2=j;
}
}
}
memset(vis,,sizeof(vis));
bfs(a1,b1,step1);
memset(vis,,sizeof(vis));
bfs(a2,b2,step2);
for(int i=;i<n;i++)//遍历所有元素,使得能走到KFC且为最小
{
for(int j=;j<k;j++)
{
if(map[i][j]=='@'&&step1[i][j]&&step2[i][j]&&(step1[i][j]+step2[i][j]<ans))//注意此处step为0代表KFC到不了
ans=step1[i][j]+step2[i][j];
}
}
printf("%d\n",ans*);
}
return ;
}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

此时能够AC 时间为31ms

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Note:需要注意下bfs的使用次数即可

2018-11-16  00:25:12  Author:LanceYu

HDU 2612 Find a way 题解的更多相关文章

  1. HDU 2612 Find a way(找条路)

    HDU 2612 Find a way(找条路) 00 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)   Problem  ...

  2. HDU.2612 Find a way (BFS)

    HDU.2612 Find a way (BFS) 题意分析 圣诞节要到了,坤神和瑞瑞这对基佬想一起去召唤师大峡谷开开车.百度地图一下,发现周围的召唤师大峡谷还不少,这对基佬纠结着,该去哪一个...坤 ...

  3. BFS(最短路) HDU 2612 Find a way

    题目传送门 /* BFS:和UVA_11624差不多,本题就是分别求两个点到KFC的最短路,然后相加求最小值 */ /***************************************** ...

  4. HDU 2612 Find a way(双向bfs)

    题目代号:HDU 2612 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2612 Find a way Time Limit: 3000/1000 M ...

  5. 题解报告:hdu 2612 Find a way(双bfs)

    Problem Description Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. L ...

  6. HDU 2612 - Find a way - [BFS]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2612 Problem DescriptionPass a year learning in Hangz ...

  7. hdu 2612 Find a way

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2612 Find a way Description Pass a year learning in H ...

  8. HDU 2612 Find a way bfs 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=2612 bfs两次就可将两个人到达所有kfc的时间求出,取两人时间之和最短的即可,这个有点不符合实情,题目应该出两 ...

  9. (广搜) Find a way -- hdu -- 2612

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=2612 Find a way Time Limit: 3000/1000 MS (Java/Others) ...

随机推荐

  1. 【LG5171】Earthquake

    [LG5171Earthquake] 题面 洛谷 题解 本题需要用到类欧几里得算法. 前置知识:类欧几里得 就是求函数\[\varphi (a,b,c,n)=\sum_{i=0}^n \left\lf ...

  2. CF1149D Abandoning Roads(图论,最短路,状态压缩,最小生成树)

    题目大意:$n$ 个点,$m$ 条边的无向图,边权只有两种,小的为 $a$,大的为 $b$. 对于每个点 $p$,询问在这张图所有的最小生成树上,$1$ 到 $p$ 的最短距离的最小值. $2\le ...

  3. TypeWriting

    头文件getputch.h /* * getputch.c */ /* 用于getch/putch的通用头文件"getputch.h" */ #ifndef __GETPUTCH ...

  4. 如何为python 2.7安装tensorflow?

    “TensorFlow在Windows上支持Python 3.5.x和3.6.x.” 因此,您无法在Windows上使用Python 2.7的tensorflow 如果您被迫使用Python 2.7, ...

  5. Qt Quick 常用元素:TabView(选项卡) 与 Slider(滑块)

    一.TabView TabView 可以实现类似 Windows 任务管理器的界面,有人叫 TabView 为标签控件,有人又称之为选项卡控件,我们知道它就是这么个东西就行了.现在来介绍 TabVie ...

  6. Laravel自定义排序

    如果数据库的status字段有0,1,2,3几种状态,如果想让status为1,2的状态排在最前面 那么可以这样: $obj = $obj->orderByRaw(DB::raw('FIELD( ...

  7. ROS消息vs服务

    1.ROS包消息/服务模式与要点 从功能上看,ROS包是信息交互和处理的基本单元.根据信息的交互和处理方式,ROS包有以下两大类: 消息发布者与订阅者 服务器与客户端 对于消息模式的包,信息的提供者主 ...

  8. Unity3d—GUI能量条

    1.打开Unity编辑器. 2.在脚本文件夹中添加C#脚本,我的是添加了skill_01这个脚本.(要自己设置文件夹,方便管理,不然文件添乱不方便管理) 3.注意,脚本的名字一旦确定就不要去改动,因为 ...

  9. 反弹Shell原理及检测技术研究

    1. 反弹Shell的概念本质 所谓的反弹shell(reverse shell),就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端. 本文会先分别讨论: ...

  10. .net core启用 autoMapper

    启用 autoMapper   autoMapper 基于约定的对象映射器 目录 安装包 添加服务 书写映射关系 安装包   需要安装两个包:AutoMapper和AutoMapper.Extensi ...