洛谷 P9575 「TAOI-2」喵了个喵 Ⅳ 题解

Solution

  • 先求出所有数的最大公约数 \(d\),然后将每个数约去 \(d\)。将约去后的数均分,约去前的数也均分。下文讨论的数都是约去 \(d\) 后的数(包括取的 \(x\))。
  • \(n\) 为偶数,取 \(x=1\),对半分即可。
  • \(n\) 不为偶数,且有奇数个偶数。取 \(x=2\),设奇数和偶数分别有 \(x,y\) 个,B 组取 \(\frac{x}{2}-1\) 个奇数,\(\frac{y+1}{2}\) 个偶数即可。因为约去了 \(d\),所以 \(x>0\)
  • \(n\) 不为偶数,且有偶数个偶数。不论取什么 \(x\) 都有奇数个奇数,无解。
  • 输出的时候要把 \(x\) 乘上 \(d\)。赛时因为这个死活调不出来。

Code

#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
using namespace std;
namespace Milkcat {
	typedef long long LL;
	typedef pair<LL, LL> pii;
    typedef vector<LL> poly;
	const int N = 1e6 + 5;
	LL n, d, x, a[N], ans[N];
	int main() {
		cin >> n;
		if (n == 1) return puts("-1"), 0;
		for (int i = 1; i <= n; i ++) cin >> a[i];
		for (int i = 1; i <= n; i ++) d = __gcd(d, a[i]);
		for (int i = 1; i <= n; i ++) a[i] /= d;
		if (n % 2 == 0) {
			x = 1;
			for (int i = n / 2 + 1; i <= n; i ++) ans[i] = 1;
		}
		if (n % 2 == 1) {
			vector<int> odd, even;
			for (int i = 1; i <= n; i ++) {
				if (a[i] % 2 == 0) even.pb(i);
				if (a[i] % 2 == 1) odd.pb(i);
			}
			if (even.size() % 2 == 1) {
				x = 2;
				for (int i = 0; i < odd.size() / 2 - 1; i ++) ans[odd[i]] = 1;
				for (int i = 0; i < (even.size() + 1) / 2; i ++) ans[even[i]] = 1;
			}
			if (even.size() % 2 == 0) x = -1;
		}
		if (x == -1) return puts("-1"), 0;
		cout << x * d << '\n';
		for (int i = 1; i <= n; i ++) cout << ans[i];
		cout << '\n';
		return 0;
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
    int T = 1;
    while (T --) Milkcat::main();
    return 0;
}
posted @ 2024-01-19 18:59  喵仔牛奶  阅读(71)  评论(0)    收藏  举报