多校(第三场)E题循环节非kmp简单做法
题意:
给一个字符串 将这个字符串从每个字符为起点的串分类输出 例如abab 它的串分别为abab baba abab baba 于是输出两种 abab的两个串起点分别是0、2,baba的是1、3。
解法:
首先我们可以观察到,每个串的长度都是相同的。我们只要找到这个字符串的最大循环节长度maxlen,就可以知道有maxlen种串,然后按照循环直接输出每种串的每个位置。
这个时候很多人用了kmp,但是这个题其实是可以用更简单的方式来找出这个循环节。最大循环节长度maxlen显然必须可以被字符串长度len整除,所以必然是len的因子,而字符串的因子个数小于50,所以我们可以直接暴力枚举len的每个因子,验证最大循环节。时间复杂度小于50*len。
以下为队友的代码
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int MAXN = 1000005;
#define INF 0X3f3f3f3f
int n, m;
int a;
char s[MAXN];
int main()
{
int T;
while (scanf("%s", s) != EOF)
{
int l = strlen(s);
int t = 0;
for (int i = 1; i <= l; i++)
{
if (l % i == 0)
{
int flag = 0;
for (int j = 0; j < i; j++)
{
for (int k = 1; k <= l / i - 1; k++)
{
if (s[j] != s[j + k * i])
{
flag = 1;
break;
}
}
}
if (flag == 0)
{
t = i;
break;
}
}
}
printf("%d\n", t);
for (int i = 0; i < t; i++)
{
printf("%d", l/t);
for (int j = 0; j < l/t; j++)
{
printf(" %d", i + t * j);
}
printf("\n");
}
}
}
查看5道真题和解析