CF1582D - Vupsen, Pupsen and 0(數學規律+構造性演算法/省選級)
阿新 • • 發佈:2021-11-08
【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
的情況,直接輸出了 F
和 S
,未考慮符號。
文 / WIDA
2021.11.8成文
首發於WIDA個人部落格,僅供學習討論
更新日記:
2021.11.8 成文