1 条题解
-
0
📝 题目大意
给定 和 ,问无限重复字符串
wbwbwwbwbwbw得到的无限字符串中,是否存在一个子串恰好包含 个w和 个b。💡 解题思路
-
题目分析:基础模式
wbwbwwbwbwbw长度为 ,其中包含 个w和 个b。由于 ,目标子串长度 。模式串是无限循环的,具有周期性,因此任何长度不超过 的子串必然出现在模式串重复足够多次后的有限前缀中。 -
算法推导:本题数据范围极小(),直接枚举即可。将基础模式重复 次得到字符串 (长度 ),足以覆盖任意一个长度 的子串的所有可能起始位置。然后枚举 中所有长度为 的子串,统计其中
w和b的数量,若与给定的 一致则输出Yes,否则枚举结束后输出No。 -
边界与细节:
- 当 或 时同样适用,但并非所有组合都合法(如样例 2: 输出
No),因为模式串中w和b的分布是固定的,并非任意比例都能凑出。 - 确保重复次数足够:,绰绰有余。若 较大(接近 ),需要保证 的长度至少为 加上一个周期长度以覆盖跨边界的子串,这里 足够。
- 子串必须连续,不能随意拼接。
- 当 或 时同样适用,但并非所有组合都合法(如样例 2: 输出
⏱️ 复杂度分析
- 时间复杂度: 的长度为 ,枚举子串起点 有 种,每个子串需要 统计字符,其中 。总复杂度为 ,常数级别,完全可行。
- 空间复杂度:仅需存储字符串 (长度 ),以及若干计数变量,空间复杂度为 。
💻 标准代码 (C++)
#include <iostream> #include <string> using namespace std; int main() { int W, B; cin >> W >> B; // 基础模式:长度为 12,包含 7 个 'w' 和 5 个 'b' string base = "wbwbwwbwbwbw"; // 将模式重复 20 次得到足够长的字符串 S(长度 240) // 由于 W + B <= 200,这足以覆盖所有可能的子串 string S; for (int i = 0; i < 20; i++) { S += base; } int len = W + B; // 目标子串的长度 bool found = false; // 枚举 S 中所有长度为 len 的子串 for (int i = 0; i + len <= S.length(); i++) { int cnt_w = 0, cnt_b = 0; // 统计当前子串中 'w' 和 'b' 的数量 for (int j = i; j < i + len; j++) { if (S[j] == 'w') cnt_w++; else cnt_b++; // 非 'w' 即 'b' } // 如果当前子串恰好包含 W 个 'w' 和 B 个 'b',则找到答案 if (cnt_w == W && cnt_b == B) { found = true; break; } } cout << (found ? "Yes" : "No") << endl; return 0; } -
- 1
信息
- ID
- 783
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者