题意:
长度为 n(偶数) 的数组中,要使 任意 a[i]+a[n-i+1]=x,一次操作可以把任意一个数变为[1,k],问需要最少多少次操作可以满足条件。
思路:
我是用 差分的思想, 当x∈[L,R]时,
- 当n次操作的话,一定可以,那么 sum[2]=n.(L=R=2);
- 对于每对数字,求出只操作一次的他们的和能到的范围,
int minn=min(a[i],a[n-i+1]);
int maxx=max(a[i],a[n-i+1]);
sum[minn+1]--;
sum[maxx+k+1]++;
- 对于每对数字,不操作的话,他们的范围是:
sum[minn+maxx]--;
sum[minn+maxx+1]++;
最后: 直接遍历sum数组,找出最小的。
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=4e5+177;
ll a[maxn];
ll sum[maxn];
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(sum,0,sizeof(sum));
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
sum[2]=n;
for(int i=1;i<=n/2;i++){
int minn=min(a[i],a[n-i+1]);
int maxx=max(a[i],a[n-i+1]);
sum[minn+1]--;
sum[maxx+k+1]++;
sum[minn+maxx]--;
sum[minn+maxx+1]++;
}
sum[1]=0;
ll ans=0x3f3f3f3f3f3f3f3f;
for(int i=2;i<=2*k;i++){
sum[i]=sum[i]+sum[i-1];
ans=min(ans,sum[i]);
}
printf("%lld\n",ans);
}
}