洛谷B4179 [厦门小学生 C++ 2024] 战线巡逻 题解
题外话
本题属于赛后补题系列,以后我会陆陆续续在这个系列中更新曾经比赛中未做出来的题。
本题做法
- 排序,贪心,差分。
思路
这题中每一个点的覆盖方式可以看做 2 种情况:
- 士兵一开始就部署在这个点上,不影响体力消耗。
- 士兵从相邻的 2 个点之一巡逻而来,体力消耗为 2 个点距离这个点的距离。
我们要使这个距离最小,可以先用差分求出每相邻 2 个需要巡逻的点之间的距离,然后对差分数组进行排序,取前 \(n-k\) 小的值相加得到答案。
当然,若直接 \(k\ge n\),就可以直接让每个士兵部署在每一个需要巡逻的点上了,直接输出 0 即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const double EPS=1e-8;
const int N=1e5+5;
long long n,k,a[N],c[N];
int main(){
cin>>k>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
if(k>=n){
cout<<0;
return 0;
}
sort(a+1,a+1+n);
for(int i=2;i<=n;i++){
c[i]=a[i]-a[i-1];
}
sort(c+2,c+1+n);
// for(int i=1;i<=n;i++) cout<<c[i]<<" ";
// cout<<endl;
long long s=0;
for(int i=2;i<=1+n-k;i++) s+=c[i];
cout<<s;
return 0;
}
AC 记录
链接。