洛谷八月月赛 II T2 题解

Content

现有 \(T\) 次询问。 每次询问给定一个长度为 \(n\) 的 01 串,记为 \(A\)。回答应是一个字符串 \(B\),满足:

  • \(B\) 是长度为 \(m\) 的 01 串。
  • \(B\) 中不存在任意一个子串与 \(A\) 相同。
  • \(B\) 中存在至少一个子序列与 \(A\) 相同。

若有多解输出任意一个解。

数据范围:\(1\leqslant n\leqslant m\)\(1\leqslant\sum m\leqslant 2\times 10^6\)\(A_i\in\{0,1\}\)

Solution

这里直接讲正解。

首先,下列情况不能够造出符合要求的 B:

  • \(n=1\)
  • \(n=m\)
  • \(n=2\) 且字符串是 0110

否则可以构造出一种方案。构造方案如下:

  1. 如果字符串形如 000...1 或者 111...0 的话,则先在第一个字符后面插入一个与第一个字符不同的字符(如果第一个字符是 1 则在后面插入 0,反过来则插入 1),然后如果长度不够的话就在后面不停地插入最后一个字符相同的字符直到长度达到 \(m\) 为止。
  2. 否则在原字符串最后一个字符之前插入 \(m-n\) 个与最后一个字符不同的字符即可。

是不是很简单呢?

Code

namespace Solution {
	iv Main() {
		MT {
			int n, m;
			read(n, m);
			string s; cin >> s;
			if(n == 1 || n == m) puts("-1");
			else {
				string ans = s.substr(0, n - 1);
				int fl0 = 1, fl1 = 1;
				F(int, i, 0, (int)ans.size() - 1) if(ans[i] != '0') fl0 = 0; else if(ans[i] != '1') fl1 = 0;
				if((fl0 && s[n - 1] == '1') || (fl1 && s[n - 1] == '0')) {
					if(n == 2) puts("-1");
					else {
						string ans2 = ""; ans2 += ans[0];
						if(ans[0] == '0') ans2 += "1";
						else ans2 += "0";
						ans2 += s.substr(1, n - 1);
						F(int, i, n + 1, m - 1) ans2 += s[n - 1];
						cout << ans2 << endl;
					}
					continue;
				}
				if(s[n - 1] == '0') {
					F(int, i, n, m - 1) ans += "1";
					ans += s.substr(n - 1, 1);
				} else {
					F(int, i, n, m - 1) ans += "0";
					ans += s.substr(n - 1, 1);
				}
				cout << ans << endl;
			}
		}
		return;
	}
}
posted @ 2021-12-15 21:30  Eason_AC  阅读(40)  评论(0)    收藏  举报