0
点赞
收藏
分享

微信扫一扫

A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11

霍华德 2022-06-24 阅读 30

原题链接: ​​https://codeforces.com/contest/1427/problem/A​​

A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_#define
测试样例

input
4
4
1 -2 3 -4
3
0 0 0
5
1 -1 1 -1 1
6
40 -31 -9 0 13 -40
output
YES
1 -2 3 -4
NO
YES
1 1 -1 1 -1
YES
-40 13 40 0 -9 -31

Note

Explanation of the first testcase: An array with the desired properties is b=[1,−2,3,−4]. For this array, it holds:

  • The first element of b is 1.
  • The sum of the first two elements of b is −1.
  • The sum of the first three elements of b is 2.
    The sum of the first four elements of b is −2.


Explanation of the second testcase: Since all values in a are 0, any rearrangement b of a will have all elements equal to 0 and therefore it clearly cannot satisfy the second property described in the statement (for example because b1=0). Hence in this case the answer is NO.

Explanation of the third testcase: An array with the desired properties is b=[1,1,−1,1,−1]. For this array, it holds:

  • The first element of b is 1.
  • The sum of the first two elements of b is 2.
  • The sum of the first three elements of b is 1.
  • The sum of the first four elements of b is 2.
  • The sum of the first five elements of b is 1.


Explanation of the fourth testcase: An array with the desired properties is b=[−40,13,40,0,−9,−31]. For this array, it holds:

  • The first element of b is −40.
  • The sum of the first two elements of b is −27.
  • The sum of the first three elements of b is 13.
  • The sum of the first four elements of b is 13.
  • The sum of the first five elements of b is 4.
  • The sum of the first six elements of b is −27.


题意: 给你一个长度为A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_ios_02的整数序列A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_#define_03,现在需要你对该序列进行重新排列使得前缀和不为A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_前缀和_04,若不存在这样的排列,则输出“NO“。

解题思路: 我们想要让所有的前缀和A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_#define_05都不为A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_前缀和_04,那么该如何进行处理呢?对于A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_前缀和_07,它是等于A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_ios_08。所以每个前缀和其实和上一个前缀和有关系,换句话说,如果我用一个A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_ios_09遍历一遍排列好的数组,A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_ios_09累加元素和。如果出现A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_#define_11,则说明不可行。 那么我们根据贪心原则,我们要使得A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_ios_12,我们要么现在前面一直放正数,然后再放负数,要么现在前面一直放负数,然后一直放正数。(注意:A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_ios_13是可以放放中间任意位置的,都没有影响) 这个时候我们就发现一个奇妙的东西了。如果正数和等于负数和,那么是不可能的,因为长度为A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_ios_02的前缀和一定为A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_前缀和_04,那么其他的情况是否一定满足呢?答案是一定的,我们一定要使得前缀和不为A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_前缀和_04,那么如果正数和大于负数和,那么我们先一直放正数,然后放A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_前缀和_04,然后放负数,就相当于是递减排序,这样前缀和是永远大于0的。如果负数和大于正数和,那么我们先一直放负数,然后放A. Avoiding Zero(前缀和+贪心)Codeforces Global Round 11_前缀和_04,然后放正数,就相当于是递增排序,这样前缀和是永远小于0的。

AC代码

/*

*
*/
#include<bits/stdc++.h> //POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int t,n;
int main(){
//freopen("in.txt", "r", stdin);//提交的时候要注释掉
IOS;
while(cin>>t){
while(t--){
cin>>n;
vector<int> num(n);
int pos=0,neg=0;//pos统计正数和,neg统计负数和。一定要初始化。
rep(i,0,n-1){
cin>>num[i];
if(num[i]>0){
pos+=num[i];
}
else if(num[i]<0){
neg+=num[i];
}
}
//目的使得前缀和不为0,故要么前面全是正数使得和最大,再用负数去减。要么前面全是负数使得和最小,再用正数去加。
if(pos+neg==0){
//这种必不可能,无论你怎么排列,长度为n的前缀和必为0.
cout<<"NO"<<endl;
}
//那么其他就可行。
else if(pos+neg>0){
//说明正数和大,先放正数,再放负数,必满足,我们直接从大到小排列即可。
sort(num.begin(),num.end(),greater<int>() );
cout<<"YES"<<endl;
rep(i,0,n-1){
cout<<num[i]<<" ";
}
cout<<endl;
}
else{
//说明负数和大,先放负数,再放正数,必满足,我们直接从小到大排列即可。
sort(num.begin(),num.end());
cout<<"YES"<<endl;
rep(i,0,n-1){
cout<<num[i]<<" ";
}
cout<<endl;
}
}
}
return 0;
}


举报

相关推荐

0 条评论