『题解』CodeForces CF1661A Array Balancing
题目大意
给定两个长度为 \(n\)(\(2 \le n \le 25\)) 的数列 \(a,b\)(\(1 \le a_i,b_i \le 10^9\)),你可以进行任意次操作:选择一个下标 \(i\),并交换 \(a_i\) 与 \(b_i\)。
经过若干次操作后,最小的 \(\sum\limits^{n-1}_{i=1}(|a_i-a_{i+1}|+|b_i-b_{i+1}|)\) 是多少?
思路
两个数相减的绝对值,就是这两个数相差多少。
那么计算 \(|a_i-a_{i+1}|\) 时,要让它最小,那么用 \(a_i,a_{i+1}\) 分别与 \(b_i,b_{i+1}\) 比大小,将小的放在 \(a\) 中,大的都放在 \(b\) 中,这样计算出来的绝对值一定是最小的。
我们只需要遍历一遍数组,计算一下相邻两项是 \(|a_i-a_{i+1}|+|b_i-b_{i+1}|\) 小还是 \(|a_i-b_i+1|+|b_i-a_i+1|\) 小,若是后者小,把 \(a_{i+1}\) 和 \(b_{i+1}\) 交换一下就行了。
最后再循环一遍,统计答案,这里注意要开 long long。
代码
#include <iostream>
#include <cmath>
using namespace std;
template<typename T=int>
inline T read(){
T X=0; bool flag=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') flag=0; ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<1)+(X<<3)+ch-'0',ch=getchar();
if(flag) return X;
return ~(X-1);
}
template<typename T=int>
inline void write(T X){
if(X<0) putchar('-'),X=~(X-1);
T s[20],top=0;
while(X) s[++top]=X%10,X/=10;
if(!top) s[++top]=0;
while(top) putchar(s[top--]+'0');
putchar('\n');
}
const int N=30;
int t,n,a[N],b[N];
long long ans;
int main(){
t=read();
while(t--){
n=read();
for(int i=1; i<=n; i++){
a[i]=read();
}
for(int i=1; i<=n; i++){
b[i]=read();
}
for(int i=1; i<n; i++){
if(abs(a[i]-a[i+1])+abs(b[i]-b[i+1])>abs(a[i]-b[i+1])+abs(b[i]-a[i+1])){
swap(a[i+1],b[i+1]); // 交换
}
}
for(int i=1; i<n; i++){
ans+=abs(a[i]-a[i+1])+abs(b[i]-b[i+1]);
}
write(ans);
ans=0;
}
return 0;
}

浙公网安备 33010602011771号