AtCoder,https://atcoder.jp/contests/abc160/tasks/abc160_c。
There is a circular pond with a perimeter of K meters, and N houses around them.
The i-th house is built at a distance of Ai meters from the northmost point of the pond, measured clockwise around the pond.
When traveling between these houses, you can only go around the pond.
Find the minimum distance that needs to be traveled when you start at one of the houses and visit all the N houses.
Input is given from Standard Input in the following format:
K N
A1 A2 ... AN
Print the minimum distance that needs to be traveled when you start at one of the houses and visit all the N houses.
20 3
5 10 15
10
If you start at the 1-st house and go to the 2-nd and 3-rd houses in this order, the total distance traveled will be 10.
20 3
0 5 15
10
If you start at the 2-nd house and go to the 1-st and 3-rd houses in this order, the total distance traveled will be 10.
虽然是英文题,但是涉及的单词不多。基本意思就是一个圆形的湖边周长为 K,湖边上有 N 个房子,第 i 个房子到正北方的距离记为 Ai。然后有一个商人,要访问这 N 个房子。要求我们寻找一个最短的访问距离。
其实这就是一个数学题。我们知道每两个房子之间的距离可以看成一个线段。这样,我们 N 个房子可以构成 N 个线段。不要忘记第 N 幢房子和第 1 幢房子也可以构成一个线段。这样,我们知道最短的距离其实就是少走了这 N 个线段中的最长距离。也就是湖的周长减去这 N 个线段中的最长距离。
不是很理解。没关系,我们使用样例数据 1 作为例子,进行详细过程分析。从样例输入 1 中,我们知道,湖周长为 20,第 1 幢房子的距离为 5,第 2 幢房子的距离为 10,第 3 幢房子的距离为 15。这样我们绘制出下图的房子分布。
那么我们就知道第一幢房子和第二幢房子之间的距离为 10 - 5 = 5,如下图红色线段所示。
第二幢房子和第三幢房子之间的距离为 15 - 10 = 5,如下图绿色线段所示。
第三幢房子和第一幢房子之间的距离为 20+5 - 15 = 10,如下图紫色线段所示。
上面的数据,我们不难看出以下几个结论:
1、所有房子之间的总距离就是湖泊的周长,5+5+10=20。
2、商人要访问这三个房子最短距离就是 5+5=10。也就是从第一幢出发,经过第二幢,到达第三幢。是不是最长的距离 10 没有走,走了其他距离。那么是不是就是湖的周长减去最大距离,20-10=10。
经过上面的样例数据分析,我们就可以非常容易的设计出算法。算法的核心就是计算出最大的线段距离。算法过程就不写了,本题过于简单。是不是发现,有点像差分的模板题,就是多了一个记录差分的最大值。
#include
using namespace std;
const int MAXN = 2e5+4;
int a[MAXN];
int main() {
int k,n;
cin>>k>>n;
int maxx = 0;
cin>>a[0];
for (int i=1; i>a[i];
maxx = max(maxx, a[i]-a[i-1]);
}
maxx = max(maxx, k+a[0]-a[n-1]);
cout << k - maxx << endl;
return 0;
}
第 N 幢房子和第 1 幢房子之间的距离,我们要注意是 k-a[n-1]+a[0]。