其他分享
首页 > 其他分享> > P8437 伟大的神 题解

P8437 伟大的神 题解

作者:互联网

题目大意

给出 \(n\), \(m\), \(k\),求满足下面条件的字符串

上面对神之字符串的定义是:字母出现次数都相同的字符串

题解

Subtask 1

既然有 \(k=1\),那么就只有一种构造的方式,使相邻两位不相同。
于是代码就出来了。

const std::vector<std::string> s{"l", "r"}; // 保证这一行只出现这一次
if (k == 1) {
	for (int i = 0; i < n; i++) {
		std::cout << s[i & 1];
	}
	return 0;
}

Subtask 2

满足 \(n=m\) 的条件,显然整个字符串都是神之字符串,于是可以用和上面构造方式相同的方式构造。

if (n == m) {
	for (int i = 0; i < n; i++) {
		std::cout << s[i & 1];
	}
	return 0;
}

Subtask 3

有一个条件 \(k \geq 3\),显然对于这样的性质,我们可以先用 lrlr…… 的方式构造出前 \(m\) 个字符,满足神之字符串的条件,然后对于剩下 \(n - m\) 个字符,我们通过这样的重复构造就可以了 llrllrllr……

if (k >= 3) {
	for (int i = 0; i < m; i++) {
		std::cout << s[i & 1];
	}
	std::string p = "lllr";
	for (int i = m; i < n; i++) {
		if (i + p.size() < n) {
			std::cout << p;
			i += p.size() - 1;
		} else {
			for (int j = 0; j < n - i; j++) {
				std::cout << p[j];
			}
			return 0;
		}
	}
}

Subtask 4

当 \(k = 2\) 时可以发现上面的那种构造方式是会被 hack 的,这里有一种 hack 的数据,我们研究一下

10 4 2

上面的代码会输出

lrlrllrllr

我们看这个子串

rlrllr

显然是神之字符串但是不符合题意的,粗暴地,我们删掉第一个 lr,在构造就可以发现:

lrllrllrll

满足了条件!

于是就可以这样的构造

for (int i = 0; i < m - 2; i++) {
	std::cout << s[i & 1];
}
std::string p = "llr";
for (int i = m - 2; i < n; i++) {
	if (i + p.size() < n) {
		std::cout << p;
		i += p.size() - 1;
	} else {
		for (int j = 0; j < n - i; j++) {
			std::cout << p[j];
		}
		return 0;
	}
}

完整代码

就不占篇幅了,这里 代码

标签:std,cout,int,题解,构造,字符串,Subtask,P8437,伟大
来源: https://www.cnblogs.com/Zheng-XiangYu/p/16488198.html