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;
}

浙公网安备 33010602011771号