题意:注释解释很清晰(逃.....)
题解:参考当时Wannafly挑战赛7的题解
如果要达到最小的值,那么最佳情况就是走到某一个点,然后找这个点两边距离最近的点,然后两点之间左右横跳(手动滑稽.jpg)
比如 对于这个,肯定是在20和21之间横跳所求值最小,然后就是枚举每一位对于p和m进行操作
时间复杂度:
#include <bits/stdc++.h>
using namespace std;
int T,n,m,p,a[200001];
int main()
{
for(scanf("%d",&T);T;T--)
{
scanf("%d%d%d",&n,&m,&p);
int pos=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]<p) pos=i;
}
long long ret=1000000000000000LL;
for(int i=1;i<=n;i++)
{
long long ans=abs(p-a[i]);
int step=max(pos-i+1,i-pos);
long long luogan=min(a[i]-a[i-1],a[i+1]-a[i]);
if(i==1) luogan=a[2]-a[1];
if(i==n) luogan=a[n]-a[n-1];
if(step<=m)
ret=min(ret,ans+luogan*(m-step));
if(step<m && pos!=0 && pos!=n)
{
if(a[i]>p)
ret=min(ret,ans+luogan*(m-step-1)+(p-a[pos])*2);
else
ret=min(ret,ans+luogan*(m-step-1)+(a[pos+1]-p)*2);
}
}
printf("%lld\n",ret);
}
return 0;
}
京公网安备 11010502036488号