D. Insert a Progression
思路:本题要发现只要插好1
和x
后,其余的数插到数组里面是不会产生贡献的。所以现在的问题转化为1
和x
怎么差产生的贡献最少?
设原数组中最小的值为 m i n min min,最大的值为 m a x max max。
如果 1 = = m i n 1 == min 1==min则可以把1放在最小值边上不会产生贡献,同理把x < max,也不会产生贡献。
考虑 x > m a x x > max x>max 和 1 < m i n 1 < min 1<min的情况:
肯定能想到优先把1
和x
放在原数组中数最大和最小的边上,如果最大值和最小值两边都还有数那么产生的贡献是
a
b
s
(
1
−
m
i
n
)
∗
2
abs(1 - min) * 2
abs(1−min)∗2和
a
b
s
(
x
−
m
a
x
)
∗
2
abs(x - max) * 2
abs(x−max)∗2,这样的贡献是两倍的,那么我们也可以把他们插到原数组第一个前面和最后一个后面,这样产生的贡献不用乘
2
2
2,我们把所有的情况产生的贡献取个最小值即可。
void solve()
{
scanf("%d %d",&n,&x);
vector<int>a;
LL ans = 0;
for(int i = 1; i <= n; i ++ ){
int xx;
cin >> xx;
a.pb(xx);
}
int sa = sz(a);
for(int i = 0; i + 1 < sa; i ++ ){
ans += abs(a[i + 1] - a[i]);
}
int xx = *max_element(all(a)), yy = *min_element(all(a));
int q = min({abs(1 - yy) * 2, abs(1 - a.front()), abs(1 - a.back())});
int p = 0;
if(xx < x) p = min({abs(x - xx) * 2, abs(x - a.front()), abs(x - a.back())});
ans += p + q;
cout << ans << endl;
}