Miku的要求
题目描述
FLY进入了一篇森林,他必须穿过这片森林。为了能安全地离开,FLY要按照守护神Miku的要求,在森林寻找葱并带给Miku。
森林可以看做是直角坐标系,并按 x、 y 轴上的单位长度划分成了 N× H 块。
FLY在地图上查出了自己、MIKU、葱、障碍物(障碍物的位置不能走)所在的位置,在没有找到葱之前,FLY叶不能通过Miku所在的那个区域。
为了确保不会迷路,FLY只向上下左右四个方向移动,每次移动要一天。
输入数据保证FLY一定能完成任务。你能计算一下,最少需要多少天才能完成任务(将葱交给MIku)
输入
第 1 行: 2 个整数,空格隔开,即 N、 M。
第二行开始输入地图,每一行用若干个数字代表地图上对应行的地形。如果地图的宽小于或
等于 40,那每一行数字恰好对应了地图上的一排土地。如果地图的宽大于 40,那每行只会给出 40 个数
字,并且保证除了最后一行的每一行都包含恰好 40 个数字。没有哪一行描述的区域分布在两个不同的
行里。
地图上的数字所对应的地形:
0: 可以通过的空地
1: 障碍,即不可通行的区域
2: FLY的位置
3: Miku的位置
4: 葱的位置
输出
最少天数
样例输入 Copy
8 4
4 1 0 0 0 0 1 0
0 0 0 1 0 1 0 0
0 2 1 1 3 0 4 0
0 0 0 4 1 1 1 0
样例输出 Copy
11
提示
【输入说明】
这片森林的长为 8,宽为 4。FLY的起始位置在第 3 行。
【输出说明】
FLY可以按这样的路线完成Miku的任务:上,左,上,下,右,右,上,右,右,下,下。最后来到Miku所在位置即为完成任务
【数据规模】
对于 60%的数据: 1≤W≤20; 1≤H≤20;
对于 80%的数据: 1≤W≤100; 1≤H≤100;
对于 100%的数据: 1≤W≤1,000; 1≤H≤1,000;
这里的关键点是要先有葱才能见初音。
同时葱不止一根!!!
于是我采用两次BFS(由于都要求全部遍历则DFS 亦可)
更新FLY到葱的距离,初音到葱的距离。取同一颗葱两者相加的最小值就是答案。
上代码
#include "bits/stdc++.h"
using namespace std;
int n,m;
int mapp[1010][1010];
int water1[1010][1010],water2[1010][1010];
int ax,ay,bx,by;
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
struct node{
int x,y,z;
};
int main()
{
// freopen("knight.in","r",stdin);
// freopen("knight.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++){
scanf("%d",&mapp[i][j]);
if(mapp[i][j]==2)ax=i,ay=j;
else if(mapp[i][j]==3) bx=i,by=j;
}
node p;p.x=ax;p.y=ay;p.z=0;
queue<node >q;
q.push(p);
while(!q.empty()){
p=q.front();q.pop();
// printf("%d %d %d\n",p.x,p.y,water1[p.x][p.y]);
for(int i=0;i<4;i++){
int ex=p.x+dx[i],ey=p.y+dy[i];
if(ex>=1&&ex<=m&&ey>=1&&ey<=n&&mapp[ex][ey]!=1&&mapp[ex][ey]!=3&&!water1[ex][ey]){
node k;k.x=ex;k.y=ey;k.z=p.z+1;water1[ex][ey]=k.z;q.push(k);
}}}
p.x=bx;p.y=by;p.z=0;
queue<node>q1;
q1.push(p);
while(!q1.empty()){
p=q1.front();q1.pop();
for(int i=0;i<4;i++){
int ex=p.x+dx[i],ey=p.y+dy[i];
if(ex>=1&&ex<=m&&ey>=1&&ey<=n&&mapp[ex][ey]!=1&&!water2[ex][ey]){
node k;k.x=ex;k.y=ey;k.z=p.z+1;q1.push(k);water2[ex][ey]=k.z;
}}}
int ans=0x7fffffff;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++){
if(mapp[i][j]!=4)continue;
// printf("%d %d\n",i,j);
if(!water2[i][j]||!water1[i][j]) continue;
ans=min(ans,water1[i][j]+water2[i][j]);
}
printf("%d",ans);
return 0;
}
浙公网安备 33010602011771号