ABC257D:蹦床

ATC-ABC257D:蹦床

题目描述

高桥居住的二维平面小镇上有\(N\)个蹦床。 第 \(i\)个蹦床位于点 \((x_i ,y_i)\) 并且具有 \(P_i\) 的高度。 高桥的跳跃能力用S表示。最初,S=0。 高桥每练一次,S就加1。

高桥可以从第 \(i\) 个蹦床跳到第 \(j\) 个蹦床当且仅当:

  • \(P_iS≥∣x_i−x_j∣+∣y_i−y_j∣\).

高桥的目标是选择一个起始蹦床,通过一些跳跃到达所选蹦床的任何蹦床。

他至少需要训练多少次才能达到目标?

数据范围

  • \(2 \leq N \leq 200\)
  • \(-10^9 \leq x_i,y_i \leq 10^9\)
  • \(1 \leq P_i \leq 10^9\)
  • \((x_i, y_i) \neq (x_j,y_j)\ (i\neq j)\)
  • All values in input are integers.

输入格式

输入遵循一下格式:

\[N\\ x_1\ y_1\ P_1\\ \vdots⋮\\ x_N\ y_N\ P_N\\ \]

输出格式

输出最少需要的训练次数


Sample Input 1

4
-10 0 1
0 0 5
10 0 1
11 0 1

Sample Output 1

2
  • 如果训练两次,可以从第二个蹦床出发,依次跳到第3、4、1个蹦床

Sample Input 2

7
20 31 1
13 4 3
-10 -15 2
34 26 5
-2 39 4
0 -50 1
5 -20 2

Sample Output 2

18

题目解析

\(P_iS≥∣x_i−x_j∣+∣y_i−y_j∣\)可以转换为

\[S≥(∣x_i−x_j∣+∣y_i−y_j∣)/P_i \]

要求向上取整。

我们可以将\((∣x_i−x_j∣+∣y_i−y_j∣)/P_i\)视为从点\(i\)至点\(j\)的距离,而\(s\)则为可行路径的最大距离即可,由于N为200,所以改写一下弗洛伊德算法,并且枚举出哪个点作为起点的\(S\)最小即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 207;
ll x[N],y[N],p[N];
ll mp[N][N];

int main() {
	int n;
	cin >> n;
	for(int i = 1 ; i <= n ; i++) {
		cin >> x[i] >> y[i] >> p[i] ;
	}

	for(int i = 1 ; i <= n ; i++) {
		for(int j = 1 ; j <= n ; j++) {
			mp[i][j] = (abs(x[i]-x[j])+abs(y[i]-y[j])+p[i]-1)/p[i];
		}
	}
	for(int k = 1 ; k <= n ; k++)
		for(int i = 1 ; i <= n ; i++)
			for(int j = 1 ; j <= n ; j++) {
				mp[i][j]=min(max(mp[i][k],mp[k][j]),mp[i][j]);
			}
	ll ans = 1e10;
	for(int i = 1 ; i <= n ; i++) {
		ll ans1 = 0;
		for(int j = 1 ; j <= n ; j++)
			ans1 = max(ans1,mp[i][j]);
		ans = min(ans,ans1);
	}
	cout << ans;
}

posted @ 2022-06-27 14:45  seekerHeron  阅读(92)  评论(0)    收藏  举报