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;
}
N - Find a way