kmp3746--kmp搗循環入門題

這題用memset就會wa,有毒


題意:給一個串,可以往這個串首尾加字符,問,最少加多少字符,使這個串變成循環串


思路:使用next[]的一個特性:

原串        abcdeabdabcde

next         0000012012345

i-next[i]   1234555999999

可見,對於長爲l的串,l-next[l]表示:把l按循環節長度最小來補齊(在首尾插入字母,而不是單向加)爲一循環串後(單獨一個不循環的串視作循環一次),此最小循環節的長度。



#include<bits/stdc++.h>

using namespace std;
const int maxn=100000+20;
char b[maxn];
int nextl[maxn];
void getnext()
{
    memset(nextl,0,sizeof(nextl));
    int l=strlen(b);
    nextl[0]=-1;
    int pb=0,pn=-1;
    while(pb<l)
    {
        if(pn==-1||b[pb]==b[pn])
        {
            pb++;
            pn++;
            nextl[pb]=pn;
        }
        else
        {
            pn=nextl[pn];
        }
    }
}

void crenext()
{
  // memset(nextl,0,sizeof(nextl));
    nextl[0]=-1;
    int j;
    int m=strlen(b)-1;
    for(int i=1;i<=m;i++)
    {

        j=nextl[i-1];
        while(b[j+1]!=b[i]&&j>=0)
        {
            j=nextl[j];
        }
        if(b[j+1]==b[i])
        nextl[i]=j+1;
        else
            nextl[i]=-1;
    }
     for(int i=0;i<=m;i++)
      nextl[i]++;
   /*   for(int i=0;i<=m;i++)
        cout<<nextl[i]<<" ";*/
}

int main()
{
    int n;
    cin>>n;
    while(n--)
    {
      //  memset(b,0,sizeof(b));
  //      cin>>b;
  scanf("%s",b);
        //crenext();
        getnext();
        int l=strlen(b);
        int sum=nextl[l];
       // cout<<l-sum<<endl;
       if(sum==0)cout<<l<<endl;
       else if(l%(l-sum)==0)cout<<0<<endl;
       else cout<<l-sum-l%(l-sum)<<endl;
     //   cout<<sum-l%(l-sum)<<endl;
    }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章