1. 程式人生 > 其它 >CF1427A Avoiding Zero 題解

CF1427A Avoiding Zero 題解

CF1427A Avoiding Zero 題解

Content

請將一個長度為 \(n\) 的數列 \(A\) 重新排序,使得這個數列所有的字首和 \(\neq 0\),或者證明沒有這樣的方案。

資料範圍:\(t\) 組資料,\(1\leqslant t\leqslant 1000\)\(1\leqslant n\leqslant 50\)\(-50\leqslant a_i\leqslant A_i\leqslant 50\)

Solution

不難發現,當且僅當所有數的和都為 \(0\) 的時候不存在滿足題目要求的方案。

否則,將所有的正整數放進一起,將所有的負整數放在一起,然後分類討論:

  • 如果所有正整數的和大於所有負整數的和的絕對值,那麼我們就考慮先把所有的正整數放在前面,再把所有的負整數放在後面,這樣可以保證字首和不為 \(0\)
  • 否則,我們先把所有的負整數放在前面,再把所有的正整數放在後面。

至於如果存在 \(0\),那就放在在所有的非零數後面就行了。

想法略顯複雜,但是實現起來也是不難的,對吧?

Code

int n, a[57], sum, sump, sumn, po[57], ne[57];

int main() {
    MT {
        n = Rint, sum = sump = sumn = 0;
        F(int, i, 0, n) po[i] = ne[i] = 0;
        F(int, i, 1, n) sum += (a[i] = Rint), sump += a[i] * (a[i] > 0), sumn += (-a[i]) * (a[i] < 0);
        if(!sum) {NO; continue;}
        YES;
        F(int, i, 1, n) if(a[i] > 0) po[++po[0]] = a[i]; else if(a[i] < 0) ne[++ne[0]] = a[i];
        if(sump > sumn) {F(int, i, 1, po[0]) print_space(po[i]); F(int, i, 1, ne[0]) print_space(ne[i]); F(int, i, 1, n - po[0] - ne[0]) printf("0 ");}
        else {F(int, i, 1, ne[0]) print_space(ne[i]); F(int, i, 1, po[0]) print_space(po[i]); F(int, i, 1, n - po[0] - ne[0]) printf("0 ");}
        puts("");
    }
    return 0;
}