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. 考试总结(橙题WA)

    又逢校内测,成绩变化大 初见三道题,暗喜AK辣 谁知数据毒,特判不到家 三题两题WA,心态已爆炸 T1(我不想再见到这道题): 附上多年前AC但是随便出(毒瘤)一组数据就可以卡掉的代码: #inclu ...

  2. [LeetCode] 126. Word Ladder II 词语阶梯之二

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  3. 【贪心】umi的函数

    原题传送门 思路 这道题乍一看很难,然而实际在草纸上一模拟,结果就出来了. 分析:这道题实际上要么无解,要么有无数个解,因而题目只要求输出了一个解(明白这点题目就做出来一半了). 题中,规定所求z满足 ...

  4. 微信JSSDK 扫描二维码

    <?php require_once('wxjssdk.class.php'); $weixin = new class_weixin(); $signPackage = $weixin-> ...

  5. Qt Quick小项目 - 登陆界面

    开发环境: win8 + Qt5.11.2 说明: 用 QML 设计一个应用的登陆界面. 效果图: 新建一个 "Qt Quick Application - empty" 工程,分 ...

  6. Loj #3111. 「SDOI2019」染色

    Loj #3111. 「SDOI2019」染色 题目描述 给定 \(2 \times n\) 的格点图.其中一些结点有着已知的颜色,其余的结点还没有被染色.一个合法的染色方案不允许相邻结点有相同的染色 ...

  7. i2c的读写时序图

    根据实际示波器的波形画的时序图,时序图不好画,小小一幅图,画了两个小时,分享之:

  8. Thinkpad S430 3364-A59 (笔记本型号)加内存条过程

    背景:13年初选购的本,目前使用发现卡得厉害,原装内存只有4G,遂寻思扩充内存. [1]准备工具 待准备工具明细: (1)螺丝刀 主要为了卸后盖的螺丝. (2)内存条 待增加的内存条,如下图: 说明一 ...

  9. Android 支持库迁移到AndroidX

    一.背景 Android系统版本在不断更新,从最初的Android 1.0到现在Google和各大手机厂商正在推的Android 10,平均下来每个年头都有一个大的版本更新.但用户正在用的手机上的An ...

  10. day11——函数名的使用、f格式化、迭代器、递归

    day11 函数名的第一类对象及使用 1.可以当作值被赋值给变量 def func(): print(1) print(func) a = func a() 2.当作元素存放在容器中 def func ...