bzoj1671: [Usaco2005 Dec]Knights of Ni 骑士

1671: [Usaco2005 Dec]Knights of Ni 骑士

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 281  Solved: 180
[Submit][Status][Discuss]

Description

Bessie is in Camelot and has encountered a sticky situation: she needs to pass through the forest that is guarded by the Knights of Ni. In order to pass through safely, the Knights have demanded that she bring them a single shrubbery. Time is of the essence, and Bessie must find and bring them a shrubbery as quickly as possible. Bessie has a map of of the forest, which is partitioned into a square grid arrayed in the usual manner, with axes parallel to the X and Y axes. The map is W x H units in size (1 <= W <= 1000; 1 <= H <= 1000). The map shows where Bessie starts her quest, the single square where the Knights of Ni are, and the locations of all the shrubberies of the land. It also shows which areas of the map can be traverse (some grid blocks are impassable because of swamps, cliffs, and killer rabbits). Bessie can not pass through the Knights of Ni square without a shrubbery. In order to make sure that she follows the map correctly, Bessie can only move in four directions: North, East, South, or West (i.e., NOT diagonally). She requires one day to complete a traversal from one grid block to a neighboring grid block. It is guaranteed that Bessie will be able to obtain a shrubbery and then deliver it to the Knights of Ni. Determine the quickest way for her to do so.

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

Input

    第1行输入2个用空格隔开的整数,即题目中提到的W、H.
    接下来输入贝茜持有的地图,每一行用若干个数字代表地图上对应行的地形.第1行描述了地图最北的那一排土地;最后一行描述的则是最南面的.相邻的数字所对应的区域是相邻的.如果地图的宽小于或等于40,那每一行数字恰好对应了地图上的一排土地.如果地图的宽大于40,那每行只会给出40个数字,并且保证除了最后一行的每一行都包含恰好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行,离骑士们不远.


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


Source

题解:分别从贝西和骑士所在位置bfs,枚举灌木位置,找最小值。

<span style="font-size:18px;">#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define ll long long
#define N 1005
using namespace std;
int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int n,m,dis[N][N][2],a[N][N],nx,ny,mx,my,hx[N*N],hy[N*N],tot=0,ans;
int x[4]={-1,0,1,0};
int y[4]={0,-1,0,1};
bool vis[N][N];
queue< pair<int,int> > q;
void bfs(int xx,int yy,int k)
{
	vis[xx][yy]=1;dis[xx][yy][k]=0;q.push(pair<int,int>(xx,yy));
	while(!q.empty())
	{
		int sx=q.front().first,sy=q.front().second;
//		cout<<sx<<' '<<sy<<endl;
		q.pop();
		for(int i=0;i<4;i++)
	   if(!vis[x[i]+sx][y[i]+sy]&&(a[x[i]+sx][y[i]+sy]==0||a[x[i]+sx][y[i]+sy]==4))
	   {
//	   	 cout<<x[i]+sx<<' '<<y[i]+sy<<"dd"<<endl;
	   	  dis[x[i]+sx][y[i]+sy][k]=dis[sx][sy][k]+1;
	   	  vis[x[i]+sx][y[i]+sy]=1;
	   	  q.push(pair<int,int>(x[i]+sx,y[i]+sy));
	   }
	}
}
int main()
{
    n=read();m=read();
    memset(a,-1,sizeof(a));
    for(int i=1;i<=m;i++)
      for(int j=1;j<=n;j++)
	  {
	  	 a[i][j]=read();
		 if(a[i][j]==2)nx=i,ny=j;
	  	 if(a[i][j]==3)mx=i,my=j;
	  	 if(a[i][j]==4)hx[++tot]=i,hy[tot]=j;
	  }
	bfs(nx,ny,0);
	memset(vis,0,sizeof(vis));
	bfs(mx,my,1);
	ans=0x7fffffff;
	for(int i=1;i<=tot;i++)
	{
		if(dis[hx[i]][hy[i]][0]!=0&&dis[hx[i]][hy[i]][1]!=0&&dis[hx[i]][hy[i]][0]+dis[hx[i]][hy[i]][1]<ans)
		ans=dis[hx[i]][hy[i]][0]+dis[hx[i]][hy[i]][1];
	}
	cout<<ans<<endl;
}
</span>



相关推荐
<p> 欢迎参加英特尔® OpenVINO™工具套件初级课程 !本课程面向零基础学员,将从AI的基本概念开始,介绍人工智能与视觉应用的相关知识,并且帮助您快速理解英特尔® OpenVINO™工具套件的基本概念以及应用场景。整个课程包含了视频的处理,深度学习的相关知识,人工智能应用的推理加速,以及英特尔® OpenVINO™工具套件的Demo演示。通过本课程的学习,将帮助您快速上手计算机视觉的基本知识和英特尔® OpenVINO™ 工具套件的相关概念。 </p> <p> 为保证您顺利收听课程参与测试获取证书,还请您于<strong>电脑端</strong>进行课程收听学习! </p> <p> 为了便于您更好的学习本次课程,推荐您免费<strong>下载英特尔® OpenVINO™工具套件</strong>,下载地址:https://t.csdnimg.cn/yOf5 </p> <p> 收听课程并完成章节测试,可获得本课程<strong>专属定制证书</strong>,还可参与<strong>福利抽奖</strong>,活动详情:https://bss.csdn.net/m/topic/intel_openvino </p> <p> 8月1日-9月30日,学习完成【初级课程】的小伙伴,可以<span style="color:#FF0000;"><strong>免费学习【中级课程】</strong></span>,中级课程免费学习优惠券将在学完初级课程后的7个工作日内发送至您的账户,您可以在:<a href="https://i.csdn.net/#/wallet/coupon">https://i.csdn.net/#/wallet/coupon</a>查询优惠券情况,请大家报名初级课程后尽快学习哦~ </p> <p> <span style="font-size:12px;">请注意:点击报名即表示您确认您已年满18周岁,并且同意CSDN基于商务需求收集并使用您的个人信息,用于注册OpenVINO™工具套件及其课程。CSDN和英特尔会为您定制最新的科学技术和行业信息,将通过邮件或者短信的形式推送给您,您也可以随时取消订阅不再从CSDN或Intel接收此类信息。 查看更多详细信息请点击CSDN“<a href="https://passport.csdn.net/service">用户服务协议</a>”,英特尔“<a href="https://www.intel.cn/content/www/cn/zh/privacy/intel-privacy-notice.html?_ga=2.83783126.1562103805.1560759984-1414337906.1552367839&elq_cid=1761146&erpm_id=7141654/privacy/us/en/">隐私声明</a>”和“<a href="https://www.intel.cn/content/www/cn/zh/legal/terms-of-use.html?_ga=2.84823001.1188745750.1560759986-1414337906.1552367839&elq_cid=1761146&erpm_id=7141654/privacy/us/en/">使用条款</a>”。</span> </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页