CodeForces练习(1)

                                                        ****Avoiding Zero****

                                                   time limit per test1 second
                                                memory limit per test256 megabytes
                                                       inputstandard input
                                                      outputstandard output

You are given an array of n integers a1,a2,…,an.

You have to create an array of n integers b1,b2,…,bn such that:

The array b is a rearrangement of the array a, that is, it contains the same values and each value appears the same number of times in the two arrays. In other words, the multisets {a1,a2,…,an} and {b1,b2,…,bn} are equal.
For example, if a=[1,−1,0,1], then b=[−1,1,1,0] and b=[0,1,−1,1] are rearrangements of a, but b=[1,−1,−1,0] and b=[1,0,2,−3] are not rearrangements of a.

For all k=1,2,…,n the sum of the first k elements of b is nonzero. Formally, for all k=1,2,…,n, it must hold
b1+b2+⋯+bk≠0.
If an array b1,b2,…,bn with the required properties does not exist, you have to print NO.

Input
Each test contains multiple test cases. The first line contains an integer t (1≤t≤1000) — the number of test cases. The description of the test cases follows.

The first line of each testcase contains one integer n (1≤n≤50) — the length of the array a.

The second line of each testcase contains n integers a1,a2,…,an (−50≤ai≤50) — the elements of a.

Output
For each testcase, if there is not an array b1,b2,…,bn with the required properties, print a single line with the word NO.

Otherwise print a line with the word YES, followed by a line with the n integers b1,b2,…,bn.

If there is more than one array b1,b2,…,bn satisfying the required properties, you can print any of them.

解法思路:

先创立一个数组(或者容器),首先要考虑的问题就是到底有没有符合条件的序列b。

序列要求对每个k而言,前k项相加都不为0.

那么想一想,有哪些条件下序列b是一定不存在的呢?

很明显,将序列a的所有元素相加,记为sum,如果sum为0,那就一定不存在了。<==>(因为不满足最后一项的之前全部元素之和为0)

所以把这个条件单独列出来,输出一个NO

接下来考虑YES的情况,题目的难度小了很多,对于YES只需要输出一种满足的情况就可以了。

继续动脑筋,怎么样才可以相对容易一点的得出序列呢?

我的第一个想法是建一个容器b,将a的第一个元素放进去,然后双重遍历a,找到合适的元素插入b中,同时删除相对应的a的元素。但是很快就困难重重,最后不得不放弃。。。

接下来就是漫长而痛苦的思考时间,拿着笔在笔记本上乱涂乱画。。。。。。最后突然想到了一点。

只要计算序列a中的正数之和以及负数(包括0)之和,把它们的绝对值进行比较,如果正数小于负数的绝对值,那么将a从小到大输出;反之从大到小不就好了吗?正好还解决了判断NO的问题。

如果正数小于负数的绝对值,也就是从小到大排序,前面的负数部分一定可以满足条件(负数加负数或者0不可能等于负数),而且因为正数小,所以正数部分的每一个数加上负数之和也必然小于0,即便加到最后一个也是小于0的。反之亦然。

于是乎!!这么一种我看起来十分完美(或许很简单)的方法就诞生了,写起来也巨快!!!

另附AC代码链接:https://paste.ubuntu.com/p/KfGwZrvwNZ/

posted @ 2020-10-26 23:34  原切  阅读(67)  评论(0)    收藏  举报