P9852 [ICPC2021 Nanjing R] Windblume Festival 题解
做法:模拟
题意:一个长为
思路:由题意可知,一次操作即将两数合并为两数之差。因此假设按操作先后顺序,
- 对于第
i 个数,若想让其符号为+ ,则需将其与第i-1 个数做一次操作,否则直接操作。 - 比如想构造
a_1-a_2-a_3+a_4+a_5 ,则:- 先从前往后找第一个符号为
+ 的数,即a_4 ,那么就将其与a_3 做一次操作,得到a_1,a_2,a_3-a_4,a_5 。 - 同样找到符号为
+ 的a_5 ,将其与a_3-a_4 做一次操作,得到a_1,a_2,a_3-a_4-a_5 。 - 最后剩下的都是
- 号了,就直接依次进行操作,得到a_1-a_2-(a_3-a_4-a_5) ,即a_1-a_2-a_3+a_4+a_5 。
- 先从前往后找第一个符号为
- 所以只需要选择相邻的数,前一个为
+ 号,后一个为- 号,两两做差,枚举最大值即可。 - 注意:当
n=1 时,直接输出a_1 ,无需进行操作。
代码:
#include<bits/stdc++.h>
#define ll long long
#define INF -0x7f7f7f7f
using namespace std;
const int N=1e6+10;
ll T,n,a[N];
int main(){
cin>>T;
while(T--){
cin>>n;
ll sum=0,ans=INF;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=abs(a[i]);//统计最大可能达到的值
}
if(n==1){//特判
cout<<a[1]<<"\n";
continue;
}
for(int i=1;i<=n;i++){
ans=max(ans,sum-abs(a[i])-abs(a[i%n+1])+a[i]-a[i%n+1]);//sum减去两数的绝对值,加上做差后的值,即为每次操作的贡献
}
cout<<ans<<"\n";
}
return 0;
}
后记:如有错误或不足请 dalao 指出。(点个再走呀!)