牛客网暑期多校训练赛第三场 E题 Sort String

题目链接

 

题意:

给了一个字符串,Si是由下标i到字符串末尾加上0到i-1组成的字符串,只有当字符串Si和Sj是相同的才算是在一组,问字符串可以分成多少组并按字典序最小的输出每组中的i下标。

 

思路:

看到这题想到了哈希,然后哈希改来改去改到95%死活不过。还有9分钟的时候队友想出来了正解,可惜来不及敲了QAQ||

这题最后是如果字符串是有循环节,并且完全由循环节构成的才能进行分组。

如果没有完全由循环节构成的话,就像这样的图,将字符串复制一份到后面,会发现中间是断开的连不上。

所以知道了这点就好做了。用KMP来算循环节的大小就好了。

 

代码:

#include 
#include 
#include 
#include 
using namespace std;
const int maxn=1e6+5;
char t[maxn];
int ne[maxn];
void makenext(const char p[],int ne[],int len)
{
    ne[0]=0;
    for(int i=1,k=0;i0&&p[i]!=p[k]) k=ne[k-1];
        if(p[i]==p[k]) k++;
        ne[i]=k;
    }
}
int main()
{
    int len;
    scanf("%s",t);
    len=strlen(t);
    makenext(t,ne,len);
    int c=len-ne[len-1];//循环节
    if(len%c==0&&ne[len-1]!=0)
    {
        printf("%d\n",c);
        int r=len/c;//每组的个数
        for(int i=0;i

 

你可能感兴趣的:(KMP,思维)