牛客小白月赛60-D-游戏购买!

  • Post author:
  • Post category:其他



题目描述


小竹成功从家里逃了出来,他决定去小胖家避一避。但是小胖要求小竹带一个刺激度大于 x 的游戏才能去他家。

为了防止被妈妈或她的朋友发现,小竹不会在道路上行走,而是在建筑物与建筑物之间穿行。

街道表现为一个 n×m 的网格,网格上只有两种建筑: 商店和住宅。商店可以通过而住宅无法通过。

小竹每次从当前所在网格可以行走到上下左右的网格中,但不能移动到网格的边界之外和别人的家中。正式的说,如果他在坐标为 (i,j)的网格里,他可以选择 (i+1,j),(i,j+1),(i−1,j),(i,j−1) , 四个方向行走。

在位置 (i,j)上的商店有一个刺激度为 wi,j的游戏,小竹可以购买他所经过的商店中的游戏并带走。若wi,j​ 为 −1 则代表这个位置是个住宅,无法通过。

注意:小胖家以及小竹家均可以被通过。

假设相邻的建筑物的距离均为 1,小竹想知道带一个刺激度高于 x 的游戏去小胖家需要的最短距离是多少?如果这是不可能实现的,请输出 −1。


输入描述


第一行三个整数 n,m,x(1≤n,m≤2000,1≤x≤109)

第二行四个整数sx,sy,ex,ey(1≤sx,ex≤n,1≤sy,ey≤m)表示起点与终点的坐标,wsx,sy​,wex,ey​均为0。

接下来 n 行,每行 m个整数,第 i 行第 j 个整数 wi,j(−1≤wi,j≤109),其中所有商店的wi,j≥1。

输入:

3 3 1
1 1 3 3
0 1 2
1 1 -1
1 1 0

输出:

6

说明:

小竹从家 (1,1) 出发,需要先前往唯一可以购买刺激度大于 1 游戏的商店 ((1,3) 买到刺激度为 2 的游戏再去小胖家。路线为  (1,1)−>(1,2)−>(1,3)−>(1,2)−>(2,2)−>(3,2)−>(3,3),总距离为6。

解析:可以说双重最短路,先算出起点到每个商店的最短距离,然后可以将每个商店作为新的起点,

注意除了”新起点“之外所有点的距离数组重新初始化为无穷大

,然后最短路算出到终点的距离即可。

#include <stdio.h>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;
const int N=2005;
long long a[N][N];//储存地图
typedef pair<int,int> PII;
vector<PII> v;//来用存商店的坐标
long long dist[N][N],n,m,k,qx,qy,zx,zy,dist2[N][N];
//dist1记录原始起点到各点的最短距离,dist2记录新起点到个点的最短距离
void solve1()//算出dist1
{
	memset(dist,0x3f,sizeof dist);
	dist[qx][qy]=0;
	queue<PII> q;
	q.push({qx,qy});
	int d1[4]={0,0,1,-1};
	int d2[4]={1,-1,0,0};
	while(q.size())
	{
		int x=q.front().first;
		int y=q.front().second;
		q.pop();
		for(int i=0;i<4;i++)
		{
			int x1=x+d1[i];
			int y1=y+d2[i];
			if(!(x1>=1&&x1<=n&&y1>=1&&y1<=m)) continue;
			if(a[x1][y1]==-1) continue;
			if(dist[x1][y1]>dist[x][y]+1)
			{
				dist[x1][y1]=dist[x][y]+1;
				q.push({x1,y1});
			}
		}
	}
}
void solve2()//算出dist2
{
	memset(dist2,0x3f,sizeof dist2);
	queue<PII> q;
	int d1[4]={0,0,1,-1};
	int d2[4]={1,-1,0,0};
	for(int i=0;i<v.size();i++)
	{
		int x=v[i].first;
		int y=v[i].second;
		dist2[x][y]=dist[x][y];//新起点初始距离其实就是原始起点到该点的距离
		q.push({x,y});
	}
	while(q.size())
	{
		int x=q.front().first;
		int y=q.front().second;
		q.pop();
		for(int i=0;i<4;i++)
		{
			int x1=x+d1[i];
			int y1=y+d2[i];
			if(!(x1>=1&&x1<=n&&y1>=1&&y1<=m)) continue;
			if(a[x1][y1]==-1) continue;
			if(dist2[x1][y1]>dist2[x][y]+1)
			{
				dist2[x1][y1]=dist2[x][y]+1;
				q.push({x1,y1});
			}
		}
	}
	if(dist2[zx][zy]>=0x3f3f3f3f) printf("-1\n");
	else printf("%lld\n",dist2[zx][zy]);
}
int main()
{
	scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&qx,&qy,&zx,&zy);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%lld",&a[i][j]);
			if(a[i][j]>k) v.push_back({i,j});
		}
	}
	solve1();
	solve2();
	return 0;
}



版权声明:本文为qq_63739337原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。