CF1839C题解

  • 分析

    首先对于最后一个元素为1的数组,显然不存在合法构造方式。为什么?因为每个1都需要至少一个数插入在它后面对它完成翻转,如果最后一个数为1,这时没有数在它后面翻转它,所以这时无法构造。

    然后我们很naive地想让每个1都只被翻转一次,那么很好想到,对于一个形如\(11\dots100\dots0\)的数组,只需要先插0然后最后一步在最后一个1后面的位置插一个0将前面全翻过来就行。

    那么如果这个数组前面有一个全0字符串,那么最后加几个0就行。
    如果这个数组前面有一个10字符串,那么我们先输出后面的,再输出前面的就行。

    那么所有合法数组都能转化成(全0字符串+)若干10字符串组合的形式(前面如果有全1字符串会合并到第一个10串中),只需要从后向前输出每个10串的构造方式,如果最前面存在全0字符串最后还要输出几个0。

  • 代码

#include <iostream>
using namespace std;
constexpr int MAXN(1000007);
int a[MAXN], ans[MAXN];
int T, n, lst, cb;
inline void read(int &temp) { cin >> temp; }
inline void work() {
	read(n);
	for (int i(1); i <= n; ++i)  read(a[i]), ans[i] = 0;
	if (a[n])  return cout << "NO" << endl, void();
	cout << "YES" << endl;
	lst = n;
	for (int i(n); ~i; --i) {
		if (a[i])  ++cb;
		if (!a[i] && cb) {
			for (int j(i + 1); j < lst; ++j)  cout << "0 ";
			cout << cb << " ";
			cb = 0, lst = i;
		}
	}
	for (int i(1); i <= lst; ++i)  cout << "0 ";
	cout << endl;
}
int main() {
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	read(T);
	while (T--)  work(); 
	return 0;
}

posted @ 2023-10-23 11:12  Kazdale  阅读(187)  评论(0编辑  收藏  举报