Find a way
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 18666 Accepted Submission(s): 6034
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.
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
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
思路:
刚看到这题感觉还行,思路一下出来了。
两人走过的路分别标记,进行广搜,每个KFC加上2人在该KFC最小步数即可。
WA了一发后,眉头一皱,发现事情并不简单。
但是找不到哪错了啊菜哭,看了讨论区才知道原来存在两人都到不了的情况ORZ。
所以最后思路是,两人的走过的路分别标记,进行广搜,每个KFC加上2人在该KFC最小步数,用3维数组存各点答案,多出来的一维记录该点被到达过几次(至多2次),最后遍历地图找到KFC上被到达2次点中最小值即可
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
#define mod 1000000007
#define ll long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
char start[205][205]; //存地图
//book标记该点是否被到达,ans存答案,mov是移动方向
int book1[205][205],book2[205][205],ans[205][205][2],mov[4][2]={0,1,1,0,0,-1,-1,0};
//x,y存坐标,step存步数,who存Y还是M,Y为1,M为2,和book对应好记一点
struct node
{
int x,y,step,who;
}st,ne;
int main(){
int row,col,i,j;
while(~scanf("%d%d",&row,&col)){
mem(book1,0);
mem(book2,0);
mem(start,0);
mem(ans,0);
queue<node> q;
for(i=1;i<=row;i++)scanf("%s",start[i]+1);
//起点入队
for(i=1;i<=row;i++){
for(j=1;j<=col;j++){
if(start[i][j]=='Y'){
st.step=0;
st.x=i;
st.y=j;
st.who=1;
book1[i][j]=1;
q.push(st);
}
if(start[i][j]=='M'){
st.step=0;
st.x=i;
st.y=j;
st.who=2;
book2[i][j]=1;
q.push(st);
}
}
}
while(!q.empty()){
st=q.front();
//判断出队比较省代码长度,应该也不会差这一点时间
if(start[st.x][st.y]=='@'){
if(ans[st.x][st.y][0])ans[st.x][st.y][1]=1; //如果该点已经被到达过第三维标记1
ans[st.x][st.y][0]+=st.step;
}
q.pop();
ne.step=st.step+1;
ne.who=st.who;
for(i=0;i<4;i++){
ne.x=st.x+mov[i][0];
ne.y=st.y+mov[i][1];
if(ne.x<1||ne.x>row||ne.y<1||ne.y>col)continue; //越界,没用这行应该也没事(每次输入前都清空地图了),不过养成习惯应该好点
//两者分别判断
if(ne.who==1&&book1[ne.x][ne.y]==0&&start[ne.x][ne.y]!='#'){
book1[ne.x][ne.y]=1;
q.push(ne);
}
if(ne.who==2&&book2[ne.x][ne.y]==0&&start[ne.x][ne.y]!='#'){
book2[ne.x][ne.y]=1;
q.push(ne);
}
}
}
//遍历地图找到KFC上被到达2次点中最小值
int minn=INF;
for(i=1;i<=row;i++)
for(j=1;j<=col;j++)
if(start[i][j]=='@'&&ans[i][j][1]==1&&ans[i][j][0]<minn)
minn=ans[i][j][0];
printf("%d\n",minn*11);
}
return 0;
}