题意:一个长度为n(n <= 100000)的序列,满足1<=ai<=i,要求确定每个数的正负号,使得所有数的总和为0.
思路:1.若所有数总和为0必有正的一半和负的一半,无论一半是奇数还是偶数,最后所有数绝对值之和必为偶数,因此所有数之和ans为奇数时直接输出No
2.ans为偶数时只需p = 0,遍历一遍若(p + a[i]) * 2 <= ans,则该数a[i]就取正,否则取负
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
const int maxn = 1e5 + 10;
int n,a[maxn],b[maxn];
int main()
{
while(scanf("%d",&n) != EOF)
{
ll ans = 0;
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
ans += a[i];
}
if(ans & 1) printf("No\n");
else
{
ll p = 0;
printf("Yes\n");
for(int i = n;i >= 1;i--)
{
if((p + a[i]) * 2 <= ans)
{
p += a[i];
b[i] = 1;
}
else b[i] = -1;
}
for(int i = 1;i <= n;i++)
{
if(i > 1) printf(" ");
printf("%d",b[i]);
}
printf("\n");
}
}
return 0;
}
本文探讨了一种针对特定序列的符号分配算法,旨在通过确定序列中每个元素的正负号,确保序列总和为零。文章首先阐述了算法的基本原理,即在序列总和为偶数的情况下,通过遍历序列并依据特定条件选择元素的符号,实现总和为零的目标。此外,还提供了算法的C++实现代码,帮助读者深入理解算法的工作机制。
2908

被折叠的 条评论
为什么被折叠?



