B. 2D Traveling

文章介绍了计算两个城市之间的最低票价问题,根据不同起点和终点在大城市内外的情况,采用不同的算法策略,包括直接距离、大城市内最小距离和大城市外最低票价的查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:样例:

输入
5
6 2 3 5
0 0
1 -2
-2 1
-1 3
2 -2
-3 -3
2 0 1 2
-1000000000 -1000000000
1000000000 1000000000
7 5 4 2
154 147
-154 -147
123 456
20 23
43 20
998 244
353 100
3 1 3 1
0 10
1 20
2 30
4 3 2 4
0 0
-100 100
-1 -1
-1 0

输出
4
4000000000
0
22
1

思路:

        根据题目意思,有三种情况,

        第一种 起点以及终点都在 大城市 k 内,那么它们之间的票价就是  0

        第二种 起点和终点都不在大城市内,那么我们先计算起点到终点之间的票价,再分别从大城市范围的诚实点中找到票价最低点,然后比较我们中间路径最短点的票价与我们直接起点到终点之间的票价,就是我们最低票价

        第三种 起点与终点,任意一个是在大城市内,在这里,我们找到不在大城市内的往大城市范围的城市点中找到最短票价,与我们直接起点到终点之间的票价,就是我们最低票价。

代码详解如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
#define endl '\n'
#define x first
#define y second
#define int long long
#define YES puts("YES")
#define NO puts("NO")
#define umap unordered_map
#define INF 0x3f3f3f3f3f3f3f3f3f
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;

using PII = pair<int,int>;

PII v[N];	// 存储城市坐标点
int n,k,s,e;	// 分别是 城市数量,大城市范围,起点城市,重点城市

inline int Dis(int a,int b)
{
	return (abs(v[a].x - v[b].x) + abs(v[a].y - v[b].y));
}

inline void solve()
{
	cin >> n >> k >> s >> e;
	for(int i = 1;i <= n;++i)
	{
		int x,y;
		cin >> x >> y;
		v[i] = {x,y};
	}
	
	// 第一种情况 如果起点与终点都在大城市范围内
	// 最低票价直接是 0
	if(s <= k && e <= k)
	{
		puts("0");
		return ;
	}
	
	// 第二种情况 如果起点与终点都不在大城市范围内
	if(s > k && e > k)
	{
		// 先计算起点直接到终点的票价
		int now = Dis(s,e);
		
		// 定义中间票价为正无穷
		int dis_s = INF;
		int dis_e = INF;
		
		// 遍历大城市寻找中间城市点中的最低票价
		for(int i = 1;i <= k;++i)
		{
			dis_s = min(dis_s,Dis(s,i));
			dis_e = min(dis_e,Dis(e,i));
		}
		
		// 比较我们中间路径最短点的票价与我们直接起点到终点之间的票价
		// 输出最低票价
		cout << min(now,(dis_s + dis_e)) << endl;
		return ;
	}
	
	// 第三种情况 起点与终点任意一点在大城市范围内
	
	// 还是一样,先计算起点直接到终点的票价
	int now = Dis(s,e);
	
	// 找到在大城市外的城市点
	if(s < e) swap(s,e);
	
	// 定义大城市外的城市点票价为正无穷
	int dist = INF;
	
	// 遍历大城市寻找大城市外的城市点最低票价
	for(int i = 1;i <= k;++i)
	{
		dist = min(dist,Dis(s,i));
	}
	
	// 输出哪个是最低票价
	cout << min(now,dist) << endl;
	return ;
}


signed main()
{
//	freopen("a.txt", "r", stdin);
//	___G;
	int _t = 1;
	cin >> _t;
	while (_t--)
	{
		solve();
	}

	return 0;
}

最后提交:

Sure, based on the given problem, here is a class diagram that represents the entities and their relationships: ``` +-----------------+ +-----------------+ | Country |<>----------| City | +-----------------+ +-----------------+ | | | | | - name | | - name | | - cities | | - roads | | | | | | + addCity() | | + addRoad() | | + removeCity() | | + removeRoad() | +-----------------+ +-----------------+ ^ | | | | | +----------------------+ | TravelingUnit | +----------------------+ | | | - type | | - driver | | - wheels/legs | | - weapons | | - canFire | | - maxSpeed | | | | + move() | | + captureByBandit() | +----------------------+ ^ | | | | | +---------------------+ | Driver | +---------------------+ | | | - nationality | | - name | | | +---------------------+ ``` Explanation: - The `Country` class represents a country and has a relationship with multiple `City` objects through the `cities` attribute. It also has attributes like `name` and methods like `addCity()` and `removeCity()` for managing cities. - The `City` class represents a city and has a relationship with multiple `Road` objects through the `roads` attribute. It has attributes like `name` and methods like `addRoad()` and `removeRoad()` for managing roads. - The `TravelingUnit` class represents a traveling unit and contains attributes like `type`, `driver`, `wheels/legs`, `weapons`, `canFire`, and `maxSpeed`. It has methods like `move()` for moving the unit and `captureByBandit()` for capturing the unit. - The `Driver` class represents a driver and contains attributes like `nationality` and `name`. It is associated with the `TravelingUnit` class. Note: This is a basic representation of the system based on the given problem statement. There might be additional classes or relationships required depending on the specific requirements of the system.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值