1. 程式人生 > 其它 >CF1582D - Vupsen, Pupsen and 0(數學規律+構造性演算法/省選級)

CF1582D - Vupsen, Pupsen and 0(數學規律+構造性演算法/省選級)

【2021.10.24】Codeforces Round #750 (Div. 2)第四題,【2021.11.08】補題

1582D - Vupsen, Pupsen and 0(源地址自⇔CF1582D

Problem

tag:

⇔數學規律、⇔構造性演算法、⇔提高階(*1600)

題意:

對於給定的 \(a_1,a_2,…,a_n\) ,你需要找到一組 \(b_1,b_2,…,b_n\) ,使得兩兩相乘的和恰好為零。

思路:

先考慮偶數的情況,我們發現,只需要兩兩一組,互相乘即可使得這一小組乘積為 \(0\)

再考慮奇數的情況,我們發現,只需要把前三個取出來單獨一組,剩下的依舊兩兩一組計算。對於單獨的那一組,我們可以這樣處理:將兩個元素合成一個,就變成了兩兩一組。要注意:合成的元素不為 \(0\)

AC程式碼:

//A WIDA Project
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int MAX=1e6+5;
LL T, n, a[MAX], F, S;
int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> T;
    while(T -- > 0) {
        cin >> n;
        for(int i = 1; i <= n ;i ++) cin >> a[i];
        if(n % 2 == 1) {
            if(a[1] + a[2] != 0) {
                F = a[1] + a[2];
                S = a[3];
                if(F * S > 0 || F < 0) cout << S << " " << S << " " << -F << " ";
                else if(S < 0) cout << -S << " " << -S << " " << F << " ";
            }else if(a[1] + a[3] != 0) {
                F = a[1] + a[3];
                S = a[2];
                if(F * S > 0 || F < 0) cout << S << " " << -F << " " << S << " ";
                else if(S < 0) cout << -S << " " << F << " " << -S << " ";
            }else if(a[2] + a[3] != 0) {
                F = a[2] + a[3];
                S = a[1];
                if(F * S > 0 || F < 0) cout << -F << " " << S << " " << S << " ";
                else if(S < 0) cout << F << " " << -S << " " << -S << " ";
            }
            for(int i = 4; i <= n; i += 2) {
                F = a[i];
                S = a[i + 1];
                if(F * S > 0 || F < 0) cout << S << " " << -F << " ";
                else if(S < 0) cout << -S << " " << F << " ";
            }
        }else {
            for(int i = 1; i <= n; i += 2) {//註釋1
                F = a[i];
                S = a[i + 1];
                if(F * S > 0 || F < 0) cout << S << " " << -F << " ";
                else if(S < 0) cout << -S << " " << F << " ";
            }
        }
        cout << "\n";
    }
    return 0;
}

錯誤次數:2次【補題2次】

原因:符號錯誤。

原因:未考慮合成元素恰好為 \(0\) 的情況。

原因:迴圈寫錯,參見注釋1處,應該是 +=2 ,誤寫成 ++

原因:對於 F * S < 0 的情況,直接輸出了 FS ,未考慮符號。


文 / WIDA
2021.11.8成文
首發於WIDA個人部落格,僅供學習討論


更新日記:
2021.11.8 成文