【一本通】A Horrible Poem
- C语言实现
- C++ 实现
💐The Begin💐点点关注,收藏不迷路💐 |
给出一个由小写英文字母组成的字符串 S,再给出 q个询问,要求回答 S某个子串的最短循环节。
如果字符串 B是字符串 A的循环节,那么 A可以由 B重复若干次得到。
输入
第一行一个正整数 n,表示 S的长度。
第二行 n个小写英文字母,表示字符串 S。
第三行一个正整数 q,表示询问个数。
下面 q行每行两个正整数 a,b,表示询问字符串 S[a…b]的最短循环节长度。
输出
依次输出 q行正整数,第 i行的正整数对应第 i个询问的答案。
样例输入
8
aaabcabc
3
1 3
3 8
4 8
样例输出
1
3
5
提示
1≤a≤b≤n≤5×105, q≤2×106
C语言实现
#include <stdio.h>
#include <string.h>// 判断子串是否是循环节,返回1表示是,0表示不是
int isPeriod(const char *s, int len, int periodLen) {for (int i = periodLen; i < len; i++) {if (s[i]!= s[i % periodLen]) { // 按循环节长度对比字符是否相等return 0;}}return 1;
}int main() {int n;scanf("%d", &n); // 输入字符串长度char s[n + 1];scanf("%s", s); // 输入字符串int q;scanf("%d", &q); // 输入询问次数while (q--) {int a, b;scanf("%d%d", &a, &b); // 输入询问子串的左右端点a--; // 转换为从0开始的下标b--;int subLen = b - a + 1; // 子串长度for (int periodLen = 1; periodLen <= subLen; periodLen++) { // 尝试不同的可能循环节长度if (subLen % periodLen == 0 && isPeriod(s + a, subLen, periodLen)) {printf("%d\n", periodLen); // 找到符合的循环节长度则输出并结束内层循环break;}}}return 0;
}
C++ 实现
#include <iostream>
#include <string>
using namespace std;// 判断子串是否是循环节,返回true表示是,false表示不是
bool isPeriod(const string& s, int len, int periodLen) {for (int i = periodLen; i < len; i++) {if (s[i]!= s[i % periodLen]) { // 按循环节长度对比字符是否相等return false;}}return true;
}int main() {int n;cin >> n; // 输入字符串长度string s;cin >> s; // 输入字符串int q;cin >> q; // 输入询问次数while (q--) {int a, b;cin >> a >> b; // 输入询问子串的左右端点int subLen = b - a + 1; // 子串长度for (int periodLen = 1; periodLen <= subLen; periodLen++) { // 尝试不同的可能循环节长度if (subLen % periodLen == 0 && isPeriod(s.substr(a - 1, subLen), subLen, periodLen)) {cout << periodLen << endl; // 找到符合的循环节长度则输出并结束内层循环break;}}}return 0;
}
💐The End💐点点关注,收藏不迷路💐 |