CF1582D - Vupsen, Pupsen and 0(数学规律+构造性算法/省选级)
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 成文