N - Find a way
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
这题卡了半天,一开始想,kfc那么多从ym去找kfc不方便,就想从每个kfc到ym的距离求出来,但是发现T了,因为kfc太多的时候,要跑很多次;
然后改成从ym加出发找每个kfc的距离,用数组存起来,然后在两种距离相加找最小的;
过程中发现自己的bfs写的不规范,之前标记走过的位置,都没有在上一层走过就标记,而是真正走到之后才标记,这样会导致比如从2.2这个点搜到了2.1,然后从1.1这个点也搜到2.1,这样就会搜两次2.1,难怪之前会出现爆内存
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include <iomanip>
#include<cmath>
#include<float.h>
#include<string.h>
#include<algorithm>
#define sf scanf
#define pf printf
//#define pb push_back
#define mm(x,b) memset((x),(b),sizeof(x))
#include<vector>
#include<queue>
//#include<map>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
typedef long long ll;
typedef long double ld;
typedef double db;
const ll mod=1e9+100;
const db e=exp(1);
using namespace std;
const double pi=acos(-1.0);
int visit[205][205];//用来存走过的状态,免得又走回去
char map[205][205];
int dir[4][2]={0,-1,0,1,-1,0,1,0};
struct node
{
int x,y,bits;
node(int a,int b){x=a;y=b;bits=0; }
node(){}
};
int ykfc[210][210],mkfc[210][210];//两个数组用来记录从y,m到每个kfc的距离
int COUNT;
void ybfs(node p)
{
int temp=0;
queue<node>v;
node t,tt;
while(!v.empty()) v.pop();
v.push(p);
while(!v.empty())
{
t=v.front();
v.pop();
if(map[t.x][t.y]=='@'&&ykfc[t.x][t.y]==0)
{
ykfc[t.x][t.y]=t.bits*11;
temp++;
}
if(temp==COUNT)
{
while(!v.empty()) v.pop();
return;
}
//visit[tt.x][tt.y]=1;原来的是这里,所以会超
rep(i,0,4)
{
tt=t;
tt.x+=dir[i][0];tt.y+=dir[i][1];
if(map[tt.x][tt.y]!='#'&&(!visit[tt.x][tt.y]))
{
tt.bits++;
visit[tt.x][tt.y]=1;//就是这里
v.push(tt);
}
}
}
}
void mbfs(node p)
{
int temp=0;
queue<node>v;
while(!v.empty()) v.pop();
node t,tt;
v.push(p);
while(!v.empty())
{
t=v.front();
v.pop();
if(map[t.x][t.y]=='@'&&mkfc[t.x][t.y]==0)
{
mkfc[t.x][t.y]=t.bits*11;
temp++;
}
if(temp==COUNT)
{
while(!v.empty()) v.pop();
return;
}
rep(i,0,4)
{
tt=t;
tt.x+=dir[i][0];tt.y+=dir[i][1];
if(map[tt.x][tt.y]!='#'&&(!visit[tt.x][tt.y]))
{
tt.bits++;
visit[tt.x][tt.y]=1;
v.push(tt);
}
}
}
}
int n,m;
int main()
{
while(~sf("%d%d",&n,&m))
{
COUNT=0;//用来记录有多少个kfc
mm(ykfc,0);//初始化
mm(mkfc,0);
mm(map,'#');//把地图其他位置都变封死,不让它乱走浪费空间和时间
rep(i,1,n+1)//输入地图
{
sf("%s",&map[i][1]);
map[i][m+1]='#';//最后一行会变成回车,要改成不可走
}
int x1,y1,x2,y2;
rep(i,1,n+1)
rep(j,1,m+1)//走一遍地图,看看有几个kfc和记录y,m的位置
{
if(map[i][j]=='@')
COUNT++;
else if(map[i][j]=='Y')
{
x1=i;y1=j;
}else if(map[i][j]=='M')
{
x2=i;y2=j;
}
}
mm(visit,0);//初始化要归0
visit[x1][y1]=1;
ybfs(node(x1,y1));//从y搜索每一个kfc
mm(visit,0);//初始化要归0
visit[x2][y2]=1;
mbfs(node(x2,y2));//从m搜索每一个kfc
int MIN=mod;
rep(i,1,n+1)
rep(j,1,m+1)
{
if(ykfc[i][j]&&mkfc[i][j])
{
MIN=min(MIN,ykfc[i][j]+mkfc[i][j]);
}
}
pf("%d\n",MIN);
}
return 0;
}