小跳蛙 解题思路
核心思路
贪心。
先给 h 数组从小到大排个序。
贪心的思路就是排序后按照以下方式移动:
也就是说:
- 如果我当前在左端点,我应该跳到(没走到过的最)右端点;
- 如果我当前在右端点,我应该跳到(没走到过的最)左端点。
实现代码如下:
示例程序
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n;
long long h[maxn], ans;
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> h[i];
sort(h+1, h+n+1);
for (int i = 0, j = n, k = 0; i < j; k ^= 1) {
ans += (h[i] - h[j]) * (h[i] - h[j]);
k ? j-- : i++;
}
cout << ans << endl;
return 0;
}
这里,我用:
- 变量
i表示左端点的编号; - 变量
j表示右端点的编号; - 变量
k表示我当前在左端点还是右端点:- 如果
k = 0 表示我当前在左端点i 准备跳到右端点j ; - 如果
k = 1 表示我当前在右端点j 准备跳到左端点i 。
- 如果
无论我当前在左端点还是右端点,跳一次的代价都是
当时:
- 如果从左端点
i 跳到右端点j ,跳过去之后(因为不会再到i 了,所以)i++ - 如果从右端点
j 调到左端点i ,跳过去之后(因为不会再到j 了,所以)j--
然后