原题链接:D. Constant Palindrome Sum
原题截图:
题目大意:
对于一串长度为n的数组a(n为偶数),要求修改其中的若干元素,使得对于任意i,有a[i]+a[n-i+1]=x,问:最少修改多少个元素
解题思路:
因为x不是一个确定的值,那么对于任意一对a[i]+a[[n-i+1],通过改变这两个的值,都可以变成从2到2*k的任意一个值,只是改变的次数有区别,假设两个数中,较小的数为a,较大的数为b,这一对的和为m,则:
改变后x的范围 | 将要更改的次数 |
---|---|
2~a+1 | 2 |
a+2~a+b-1 | 1 |
a+b | 0 |
a+b+1~b+k | 1 |
b+k+1~2*k | 2 |
那么只需要对每一对a[i]和a[n-i+1]进行这样的处理,加上打标记的操作,遍历出需要更改次数最少的即可
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int len=2e5+10;
const int inf=0x3f3f3f3f;
int t,n,k,a[len],flag[len*2];
int l,r,midl,mid,midr;
int tag,minn;
int main(){
scanf("%d",&t);
while(t--){
tag=0;
minn=inf;
memset(flag,0,sizeof(flag));
scanf("%d%d",&n,&k);
l=2;
r=2*k;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n/2;i++){
midl=min(a[i],a[n-i+1])+1;
mid=a[i]+a[n-i+1];
midr=max(a[i],a[n-i+1])+k;
flag[l]+=2;
flag[midl]-=2;
flag[midl]+=1;
flag[mid]-=1;
flag[mid+1]+=1;
flag[midr+1]-=1;
flag[midr+1]+=2;
flag[r+1]-=2;
}
for(int i=l;i<=r;i++){
tag+=flag[i];
if(tag<minn){
minn=tag;
}
}
printf("%d\n",minn);
}
return 0;
}