Codeforces Round #636 (Div. 3) 比赛人数12253
[codeforces 1343D] Constant Palindrome Sum 寻找需改变区间的边界+前缀和
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址http://codeforces.com/contest/1343/problem/D
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
D - Constant Palindrome Sum | GNU C++17 | Accepted | 62 ms | 2300 KB |
样例模拟如下
4 2
1 2 1 2
0
和值范围1+1=2,3,2+2=4
和值范围 2 3 4
(1,2)在和值范围内需改变的数字个数 1 0 1
(2,1)在和值范围内需改变的数字个数 1 0 1
所有数据在和值范围内需改变的数字个数 2 0 2
输出结果0
4 3
1 2 2 1
1
和值范围1+1=2,3,4,5,3+3=6
和值范围 2 3 4 5 6
(1,1)在和值范围内需改变的数字个数 0 1 1 2 2
(2,2)在和值范围内需改变的数字个数 2 1 0 1 2
所有数据在和值范围内需改变的数字个数 2 1 1 3 4
输出结果1
8 7
6 1 1 7 6 3 4 6
4
和值范围1+1=2,3,4,5,6,7,8,9,10,11,12,13,7+7=14
和值范围 2 3 4 5 6 7 8 9 10 11 12 13 14
(6,6)在和值范围内需改变的数字个数 2 2 2 2 2 1 1 1 1 1 0 1 2
(1,4)在和值范围内需改变的数字个数 1 1 1 0 1 1 1 1 1 1 2 2 2
(1,3)在和值范围内需改变的数字个数 1 1 0 1 1 1 1 1 1 2 2 2 2
(7,6)在和值范围内需改变的数字个数 2 2 2 2 2 1 1 1 1 1 1 0 1
所有数据在和值范围内需改变的数字个数 6 6 5 5 6 4 4 4 4 5 5 5 7
输出结果4
6 6
5 2 6 1 3 4
4
和值范围1+1=2,3,4,5,6,7,8,9,10,11,6+6=12
和值范围 2 3 4 5 6 7 8 9 10 11 12
(5,4)在和值范围内需改变的数字个数 2 2 2 1 1 1 1 0 1 1 2
(2,3)在和值范围内需改变的数字个数 2 1 1 0 1 1 1 1 2 2 2
(6,1)在和值范围内需改变的数字个数 1 1 1 1 1 0 1 1 1 1 1
所有数据在和值范围内需改变的数字个数 5 4 4 2 6 2 3 2 4 5 5
输出结果2
手工算法如下
8 7
6 1 1 7 6 3 4 6
4
和值范围1+1=2,3,4,5,6,7,8,9,10,11,12,13,7+7=14
和值范围 2 3 4 5 6 7 8 9 10 11 12 13 14
(6,6)在和值范围内需改变的数字个数 2 2 2 2 2 1 1 1 1 1 0 1 2
(1,4)在和值范围内需改变的数字个数 1 1 1 0 1 1 1 1 1 1 2 2 2
(1,3)在和值范围内需改变的数字个数 1 1 0 1 1 1 1 1 1 2 2 2 2
(7,6)在和值范围内需改变的数字个数 2 2 2 2 2 1 1 1 1 1 1 0 1
所有数据在和值范围内需改变的数字个数 6 6 5 5 6 4 4 4 4 5 5 5 7
输出结果4
和值范围 1 2 3 4 5 6 7 8 9 10 11 12 13 14
(6,6)在和值范围内需改变区间边界 2 1 2
(1,4)在和值范围内需改变区间边界 2 1 2
(1,3)在和值范围内需改变区间边界 2 1 2
(7,6)在和值范围内需改变区间边界 2 1
所有数据在和值范围内的前缀和 6 6 6 6 6 4 4 4 4 5 6 6 7
扣除重复6+6=12,1+4=5,1+3=4,7+6=13
和值范围 1 2 3 4 5 6 7 8 9 10 11 12 13 14
扣除重复 -1 -1 -1 -1
所有数据在和值范围内的前缀和 6 6 5 5 6 4 4 4 4 5 5 5 7
输出结果4
具体实现细节可看代码
#include <cstdio>
#include <algorithm>
#define maxn 200010
using namespace std;
int a[maxn],cnt[maxn<<1];
int main(){
int t,i,j,n,k,p,q,ans;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(i=1;i<=2*k+1;i++)cnt[i]=0;//初始化
for(i=1;i<=n/2;i++){
p=a[i],q=a[n-i+1];
if(p<q)swap(p,q);//保证p>=q
cnt[1]+=2,cnt[1+q]--,cnt[p+k+1]++;//区间边界计算,cnt[1]是为了数据处理而引入的
}
for(i=2;i<=2*k+1;i++)
cnt[i]+=cnt[i-1];//前缀和
for(i=1;i<=n/2;i++)cnt[a[i]+a[n-i+1]]--;//扣除重复
ans=1e6;
for(i=1;i<=2*k;i++)ans=min(ans,cnt[i]);//找最小
printf("%d\n",ans);
}
}