CF709B Checkpoints 题解
解析
在该题目中,经过其中 \(n-1\) 个点说明要去掉一个点不走。
要求经过 \(n-1\) 个点的最小距离,只需计算到最左边和最右边的最短距离即可,因为只要到达这两个点,就意味着其间所有的点全部都经过了一遍,符合题意。
那么“去掉一个点不走”,需要去掉哪一个点呢?这个问题可分为两种情况:
- 去掉最左右两点
- 去掉它们之间的点
根据上面的推论,只有最左右两点影响最终结果,所以只有去掉最左右两点才可能得到最小行走距离,故只需要对比去掉左右那个点得到的行走距离,就能得到答案。
具体实现
我们可以使用变量 right1、right2 和变量 left1、left2 来分别计算点 \(a\) 往右走的最大、次大距离和往左走的最大、次大距离。
这样,最后只需要计算去掉 right1 或去掉 left1 得到的答案即可。
注意,先往左走和先往右走得到的答案是不同的,故需要再次判断。
\(\texttt{\textcolor{Green}{Accepted} 代码}\)
#include<cstdio>
#include<algorithm>
using namespace std;
int n,a;
int left1,left2; //分别是a往左第一大的距离和第二大的距离
int right1,right2; //分别是a往右第一大的距离和第二大的距离
int ans;
int MIN(int x1,int x2,int x3,int x4) //四个数的最小值函数
{
return min(min(x1,x2),min(x3,x4));
}
int main()
{
scanf("%d%d",&n,&a);
for(int i=1;i<=n;i++)
{
int tmp;
scanf("%d",&tmp);
if(tmp>a) //tmp在a右边
{
if(tmp-a>right1)
{
right2=right1;
right1=tmp-a;
}
else if(tmp-a>right2)
right2=tmp-a;
//更新right1和right2
}
if(tmp<a) //tmp在a左边
{
if(a-tmp>left1)
{
left2=left1;
left1=a-tmp;
}
else if(a-tmp>left2)
left2=a-tmp;
//更新left1和left2
}
}
ans=MIN(left2*2+right1,right1*2+left2,left1*2+right2,right2*2+left1);
//计算最最小总行走距离
printf("%d\n",ans);
return 0;
}
2022-04-10 21:00 撰写于洛谷,2025-08-25 17:05 迁移至博客园。
本文采用 「CC-BY-NC 4.0」 创作共享协议,转载请注明作者及出处,禁止商业使用。
作者:Jerrycyx,原文链接:https://www.cnblogs.com/jerrycyx/p/19057353

浙公网安备 33010602011771号