bzoj1671 Knights of Ni 骑士 BFS


Description

 贝茜遇到了一件很麻烦的事:她无意中闯入了森林里的一座城堡,如果她想回家,就必须穿过这片由骑士们守护着的森林.为了能安全地离开,贝茜不得不按照骑士们的要求,在森林寻找一种特殊的灌木并带一棵给他们.当然,贝茜想早点离开这可怕的森林,于是她必须尽快完成骑士们给的任务,贝茜随身带着这片森林的地图,地图上的森林被放入了直角坐标系,并按x,y轴上的单位长度划分成了W×H(1≤W,H≤1000)块,贝茜在地图上查出了她自己以及骑士们所在的位置,当然地图上也标注了她所需要的灌木生长的区域.某些区域是不能通过的(比如说沼泽地,悬崖,以及食人兔的聚居地).在没有找到灌木之前,贝茜不能通过骑士们所在的那个区域,为了确保她自己不会迷路,贝茜只向正北、正东、正南、正西四个方向移动(注意,她不会走对角线).她要走整整一天,才能从某块区域走到与它相邻的那块区域.    输入数据保证贝茜一定能完成骑士的任务.贝茜希望你能帮她计算一下,她最少需要多少天才可脱离这可怕的地方?

Input

    第1行输入2个用空格隔开的整数,即题目中提到的W、H.
    接下来输入贝茜持有的地图,每一行用若干个数字代表地图上对应行的地形.第1行描述了地图最北的那一排土地;最后一行描述的则是最南面的.相邻的数字所对应的区域是相邻的.如果地图的宽小于或等于40,那每一行数字恰好对应了地图上的一排土地.没有哪一行描述的区域分布在两个不同的行里.
    地图上的数字所对应的地形:
    0:贝茜可以通过的空地
    1:由于各种原因而不可通行的区域
    2:贝茜现在所在的位置
    3:骑士们的位置
    4:长着贝茜需要的灌木的土地

Output

    输出一个正整数D,即贝茜最少要花多少天才能完成骑士们给的任务.

Sample Input

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

INPUT DETAILS:

Width=8, height=4. Bessie starts on the third row, only a few squares away
from the Knights.

Sample Output

11

HINT

 这片森林的长为8,宽为4.贝茜的起始位置在第3行,离骑士们不远.


    贝茜可以按这样的路线完成骑士的任务:北,西,北,南,东,东,北,东,东,南,南.她在森林的西北角得到一株她需要的灌木,然后绕过障碍把它交给在东南方的骑士.


前排提醒:bzoj上题目翻译有误,不存在一行只会有最多40个字符, 还害得我WA了一发。
题目很简单,是很裸的bfs。从2出发,记录在不经过3的路线中到达每个4的时间,再从3出发记录不经过2的路线中到达每个4的时间,最后能被两条路线共同经过的4中两段时间加起来最小的就是答案了。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,m,ans=99999999;
int a[1005][1050];
int sx,sy,ex,ey;
bool vis[1005][1050];
int fx[4]={1,-1,0,0};
int fy[4]={0,0,-1,1};
int dis[1005][1050],dis2[1005][1050];
struct node{
	int x,y;
};
void bfs1(int s,int t)
{
	queue<node> q;
	memset(vis,0,sizeof(vis));
	memset(dis,-1,sizeof(dis));
	q.push((node){s,t});
	vis[s][t]=1;
	dis[s][t]=0;
	while(!q.empty())
	{
		node now=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			node nex;
			nex.x=now.x+fx[i],nex.y=now.y+fy[i];
			if(nex.x<1 || nex.x>n || nex.y<1 || nex.y>m || a[nex.x][nex.y]==1 || a[nex.x][nex.y]==3 || vis[nex.x][nex.y]==1)
			continue;
			dis[nex.x][nex.y]=dis[now.x][now.y]+1;
			vis[nex.x][nex.y]=1;
			q.push(nex);
		}
	}
}
void bfs2(int s,int t)
{
	queue<node> q;
	memset(vis,0,sizeof(vis));
	memset(dis2,-1,sizeof(dis2));
	q.push((node){s,t});
	vis[s][t]=1;
	dis2[s][t]=0;
	while(!q.empty())
	{
		node now=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			node nex;
			nex.x=now.x+fx[i],nex.y=now.y+fy[i];
			if(nex.x<1 || nex.x>n || nex.y<1 || nex.y>m || a[nex.x][nex.y]==1 || a[nex.x][nex.y]==2 || vis[nex.x][nex.y]==1)
			continue;
			dis2[nex.x][nex.y]=dis2[now.x][now.y]+1;
			vis[nex.x][nex.y]=1;
			q.push(nex);
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	swap(n,m);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		scanf("%d",&a[i][j]);
		if(a[i][j]==2)
		sx=i,sy=j;
		if(a[i][j]==3)
		ex=i,ey=j;
	}
	bfs1(sx,sy);
	bfs2(ex,ey);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		if(a[i][j]==4)
		{
			if(dis[i][j]==-1 || dis2[i][j]==-1)
			continue;
			ans=min(ans,dis[i][j]+dis2[i][j]);
		}
	}
	cout<<ans<<endl;
	return 0;
}


相关推荐
程序员的必经之路! 【限时优惠】 现在下单,还享四重好礼: 1、教学课件免费下载 2、课程案例代码免费下载 3、专属VIP学员群免费答疑 4、下单还送800元编程大礼包 【超实用课程内容】  根据《2019-2020年中国开发者调查报告》显示,超83%的开发者都在使用MySQL数据库。使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能!   套餐中一共包含2门MySQL数据库必学的核心课程(共98课时)   课程1:《MySQL数据库从入门到实战应用》   课程2:《高性能MySQL实战课》   【哪些人适合学习这门课程?】  1)平时只接触了语言基础,并未学习任何数据库知识的人;  2)对MySQL掌握程度薄弱的人,课程可以让你更好发挥MySQL最佳性能; 3)想修炼更好的MySQL内功,工作中遇到高并发场景可以游刃有余; 4)被面试官打破沙锅问到底的问题问到怀疑人生的应聘者。 【课程主要讲哪些内容?】 课程一:《MySQL数据库从入门到实战应用》 主要从基础篇,SQL语言篇、MySQL进阶篇三个角度展开讲解,帮助大家更加高效的管理MySQL数据库。 课程二:《高性能MySQL实战课》主要从高可用篇、MySQL8.0新特性篇,性能优化篇,面试篇四个角度展开讲解,帮助大家发挥MySQL的最佳性能的优化方法,掌握如何处理海量业务数据和高并发请求 【你能收获到什么?】  1.基础再提高,针对MySQL核心知识点学透,用对; 2.能力再提高,日常工作中的代码换新貌,不怕问题; 3.面试再加分,巴不得面试官打破沙锅问到底,竞争力MAX。 【课程如何观看?】  1、登录CSDN学院 APP 在我的课程中进行学习; 2、移动端:CSDN 学院APP(注意不是CSDN APP哦)  本课程为录播课,课程永久有效观看时长 【资料开放】 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化。  下载方式:电脑登录课程观看页面,点击右侧课件,可进行课程资料的打包下载。
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页