ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P8437 伟大的神 题解

2022-07-17 20:03:47  阅读:177  来源: 互联网

标签:std cout int 题解 构造 字符串 Subtask P8437 伟大


题目大意

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

  • 只包含 lr
  • 总长是 \(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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有