点击打开题目链接
题目大意
给定n个数,满足1<=a[i]<=i;
使其中某些数变成倒数使得n个数总和为0;
思路:
结论:n个数可以组成1~sum[n]的任意数
证明:
当n = 1时, a[1] = 1 = sum[1] 满足;
假设当n = k时满足;
当n = k + 1时:
sum[k+1] = sum[k] + a[k+1];
因此只需证明能凑出sum[k]+1 ~ sum[k+1]的所有整数即可。
设p满足1<=p<=a[k+1]
∵sum[k] + p = sum[k] + a[k+1] - (a[k+1] - p);
并且 1<=a[k]<=k
∴sum[k] >= k && a[k+1] - p <= k;
因为前k个数能凑出a[k+1] - p;
∴前n个数能凑出1~sum[n]的所有数。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 5;
typedef long long ll;
struct a{
int id, x;
bool operator < (const a & rhs) const {
return x > rhs.x;
}
}p[maxn];
int po[maxn];
int n;
int main() {
//ios::sync_with_stdio(false),cin.tie(0);
//freopen("D:\\input.txt", "r", stdin);
//freopen("D:\\output.txt", "w", stdout);
while(cin >> n) {
memset(p, 0, sizeof(p));
memset(po, 0, sizeof(po));
ll sum = 0;
for(int i = 0; i < n; i++) {
cin >> p[i].x;
p[i].id = i;
sum += p[i].x;
}
if(sum % 2) cout << "No" << endl;
else {
cout << "Yes" << endl;
sort(p, p + n);
sum = sum / 2;
for(int i = 0; i < n; i++) {
if(p[i].x <= sum) {
po[p[i].id] = 1;
sum -= p[i].x;
}
else po[p[i].id] = -1;
}
//cout << po[1] << ' ' << po[2] << ' ' << po[3] << ' ' << po[4] << "QAQ" << endl;
for(int i = 0; i < n; i++) {
if(i == 0) printf("%d", po[i]);
else printf(" %d", po[i]);
}
printf("\n");
}
}
return 0;
}