P8437 伟大的神 题解
作者:互联网
题目大意
给出 \(n\), \(m\), \(k\),求满足下面条件的字符串
- 只包含
l
或r
- 总长是 \(n\)
- 最多有 \(k\) 个相同字符连在一起
- 最长的神之字符串长度为 \(m\)
上面对神之字符串的定义是:字母出现次数都相同的字符串
题解
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