把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

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;	 	 	
}
posted @ 2021-07-05 15:48  BLUE_ROBIN  阅读(177)  评论(0)    收藏  举报
Live2D
浏览器标题切换
浏览器标题切换end