💐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💐点点关注,收藏不迷路💐
|