zoukankan      html  css  js  c++  java
  • [kuangbin专题] KMP

    https://vjudge.net/contest/278481

    A - Oulipo

    可重叠匹配,KMP裸题

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cstring>
     4 using namespace std;
     5 const int MAXW=1e4+5;
     6 const int MAXT=1e6+5;
     7 char strW[MAXW],strT[MAXT];
     8 int lenW,lenT;
     9 int Next[MAXW];
    10 void GetNext()
    11 {
    12     int k=Next[0]=-1;
    13     int j=0;
    14     while(j<lenW)
    15     {
    16         if(k==-1||strW[k]==strW[j]) Next[++j]=++k;
    17         else k=Next[k];
    18     }
    19 }
    20 int kmp()
    21 {
    22     int i=0,j=0,ans=0;
    23     while(i<lenT)
    24     {
    25         if(j==-1||strT[i]==strW[j]) ++i,++j;
    26         else j=Next[j];
    27         if(j==lenW)
    28         {
    29             ans++;
    30             j=Next[j];
    31         }
    32     }
    33     return ans;
    34 }
    35 int read()
    36 {
    37     int s=1,x=0;char ch=getchar();
    38     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    39     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    40     return s*x;
    41 }
    42 int main()
    43 {
    44     int cas=read();
    45     while(cas--)
    46     {
    47         scanf("%s",strW);
    48         scanf("%s",strT);
    49         lenW=strlen(strW);
    50         lenT=strlen(strT);
    51         GetNext();
    52         /*for(int i=1;i<=lenW;++i)
    53         cout<<Next[i]<<' ';*/
    54         cout<<kmp()<<endl;
    55     }
    56 }
    View Code

    B - Number Sequence

    KMP裸题

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define ull unsigned long long
     4 #define ls(p) (p<<1)
     5 #define rs(p) (p<<1|1)
     6 using namespace std;
     7 const int MAXN=1e6+5;
     8 const int MAXM=1e4+5;
     9 int n,m;
    10 int a[MAXN],b[MAXM];
    11 int Next[MAXM];
    12 void GetNext()
    13 {
    14     int k=Next[0]=-1;
    15     int j=0;
    16     while(j<m)
    17     {
    18         if(k==-1||b[k]==b[j]) Next[++j]=++k;
    19         else k=Next[k];
    20     }
    21 }
    22 int kmp()
    23 {
    24     int i=0,j=0,ans=-1;
    25     while(i<n)
    26     {
    27         if(j==-1||a[i]==b[j]) ++i,++j;
    28         else j=Next[j];
    29         if(j==m)
    30         {
    31             ans=i-j+1;
    32             break;
    33         }
    34     }
    35     return ans;
    36 }
    37 int read()
    38 {
    39     int x=0,s=1;char ch=getchar();
    40     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    41     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    42     return x*s;
    43 }
    44 int main()
    45 {
    46     int test=read();
    47     while(test--)
    48     {
    49         n=read();m=read();
    50         for(int i=0;i<n;++i) a[i]=read();
    51         for(int i=0;i<m;++i) b[i]=read();
    52         GetNext();
    53         printf("%d
    ",kmp());
    54     }
    55     return 0;
    56 }
    View Code

    C - Period

    如果对于Next数组中的 i,符合 i%(i-Next[i])==0&&Next[i]!=0 则说明字符串循环,而且循环节长度为:i-Next[i]  循环次数为:i/(i-Next[i])

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=1e6+5;
    28 string str;
    29 int Next[MAXN],len;
    30 void GetNext()
    31 {
    32     int k=Next[0]=-1;
    33     int j=0;
    34     while(j<len)
    35     {
    36         if(k==-1||str[k]==str[j]) Next[++j]=++k;
    37         else k=Next[k];
    38     }
    39 }
    40 int read()
    41 {
    42     int s=1,x=0;
    43     char ch=getchar();
    44     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    45     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    46     return x*s;
    47 }
    48 int main()
    49 {
    50     int id=0;
    51     ios::sync_with_stdio(false);
    52     cin.tie(0);cout.tie(0);
    53     while(cin>>len,len)
    54     {
    55         cout<<"Test case #"<<++id<<"
    ";
    56         cin>>str;
    57         GetNext();
    58         for(int i=1;i<=len;++i)
    59         {
    60             if(Next[i]&&i%(i-Next[i])==0)
    61             cout<<i<<' '<<i/(i-Next[i])<<"
    ";
    62         }
    63         cout<<endl;
    64     }
    65     return 0;
    66 }
    View Code

    D - Power Strings

    同上,Next数组求最小循环节

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=1e6+5;
    28 string str;
    29 int Next[MAXN],len;
    30 void GetNext()
    31 {
    32     int k=Next[0]=-1;
    33     int j=0;
    34     while(j<len)
    35     {
    36         if(k==-1||str[k]==str[j]) Next[++j]=++k;
    37         else k=Next[k];
    38     }
    39 }
    40 int read()
    41 {
    42     int s=1,x=0;
    43     char ch=getchar();
    44     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    45     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    46     return x*s;
    47 }
    48 int main()
    49 {
    50     ios::sync_with_stdio(false);
    51     cin.tie(0);cout.tie(0);
    52     while(true)
    53     {
    54         cin>>str;
    55         if(str[0]=='.') return 0;
    56         len=str.size();
    57         GetNext();
    58         if(Next[len]==0||len%(len-Next[len])) cout<<1<<endl;
    59         else cout<<len/(len-Next[len])<<endl;
    60     }
    61     return 0;
    62 }
    View Code

    E - Count the string

    求出每个前缀在串中出现的次数之和。

    枚举i,对于S[1..i],和前缀S[1..j]相等的可能是后缀S[i-j+1..i],

    利用Next数组,Next[i]表示S[1..i]的最长公共前缀后缀,Next[Next[i]]表示S[1..i]的第二长公共前缀后缀...,直到为0

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=2e5+5;
    28 const int MOD=10007;
    29 string str;
    30 int Next[MAXN],len;
    31 void GetNext()
    32 {
    33     int k=Next[0]=-1;
    34     int j=0;
    35     while(j<len)
    36     {
    37         if(k==-1||str[k]==str[j]) Next[++j]=++k;
    38         else k=Next[k];
    39     }
    40 }
    41 int read()
    42 {
    43     int s=1,x=0;
    44     char ch=getchar();
    45     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    46     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    47     return x*s;
    48 }
    49 void solve()
    50 {
    51     int ans=0;
    52     GetNext();
    53     for(int i=1;i<=len;++i)
    54     {
    55         int tmp=i;
    56         while(tmp)
    57         {
    58             ans=(ans+1)%MOD;
    59             tmp=Next[tmp];
    60         }
    61     }
    62     cout<<ans<<endl;
    63 }
    64 int main()
    65 {
    66     ios::sync_with_stdio(false);
    67     cin.tie(0);cout.tie(0);
    68     int test;cin>>test;
    69     while(test--)
    70     {
    71         cin>>len>>str;
    72         solve();
    73     }
    74     return 0;
    75 }
    View Code

    F - Cyclic Nacklace

    最小循环节长度len-Next[len]

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=1e5+5;
    28 string str;
    29 int Next[MAXN],len;
    30 void GetNext()
    31 {
    32     int k=Next[0]=-1;
    33     int j=0;
    34     while(j<len)
    35     {
    36         if(k==-1||str[k]==str[j]) Next[++j]=++k;
    37         else k=Next[k];
    38     }
    39 }
    40 int read()
    41 {
    42     int s=1,x=0;
    43     char ch=getchar();
    44     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    45     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    46     return x*s;
    47 }
    48 void solve()
    49 {
    50     GetNext();
    51     if(Next[len]==0) cout<<len<<endl;
    52     else if(len%(len-Next[len])==0) cout<<0<<"
    ";//已经是循环串 
    53     else 
    54     {
    55         int T=len-Next[len];//最小循环节长度
    56         cout<<(len/T+1)*T-len<<"
    "; 
    57     }
    58 }
    59 int main()
    60 {
    61     ios::sync_with_stdio(false);
    62     cin.tie(0);cout.tie(0);
    63     int test;cin>>test;
    64     while(test--)
    65     {
    66         cin>>str;
    67         len=str.size();
    68         solve();
    69     }
    70     return 0;
    71 }
    View Code

    G - Simpsons’ Hidden Talents

    找字符串s1的前缀,字符串s2的后缀,使得它们相同且最长。

    令str=s1+s2,求Next数组即可

    注意:Next[len]是最长公共前缀后缀,Next[len]-1不一定是第二长的公共前缀后缀,而是Next[Next[len]],下一个是Next[Next[Next[len]]]...

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=1e5+5;
    28 string s1,s2,str;
    29 int Next[MAXN],len;
    30 void GetNext()
    31 {
    32     int k=Next[0]=-1;
    33     int j=0;
    34     while(j<len)
    35     {
    36         if(k==-1||str[k]==str[j]) Next[++j]=++k;
    37         else k=Next[k];
    38     }
    39 }
    40 int read()
    41 {
    42     int s=1,x=0;
    43     char ch=getchar();
    44     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    45     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    46     return x*s;
    47 }
    48 int main()
    49 {
    50     ios::sync_with_stdio(false);
    51     cin.tie(0);cout.tie(0);
    52     while(cin>>s1>>s2)
    53     {
    54         str=s1+s2;
    55         len=str.size();
    56         GetNext();
    57         if(Next[len]==0) cout<<0<<endl;
    58         else 
    59         {
    60             int lens=min(s1.size(),s2.size()),ans=Next[len];
    61             while(ans>lens)
    62             {
    63                 ans=Next[ans];
    64             }
    65             cout<<str.substr(0,ans)<<' '<<ans<<endl;
    66         }
    67     }
    68     return 0;
    69 }
    View Code

    H - Milking Grid

    Hash后求Next数组

    https://blog.csdn.net/MaxMercer/article/details/76168361

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=1e4+5;
    28 const int MAXM=80;
    29 const int Base=23333;
    30 string str[MAXN];
    31 ull row[MAXN],col[MAXM];
    32 int Next_r[MAXM],Next_c[MAXN];
    33 int n,m;
    34 int read()
    35 {
    36     int s=1,x=0;
    37     char ch=getchar();
    38     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    39     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    40     return x*s;
    41 }
    42 void GetNext_r()
    43 {
    44     int k=Next_r[0]=-1;
    45     int j=0;
    46     while(j<m)
    47     {
    48         if(k==-1||col[k]==col[j]) Next_r[++j]=++k;
    49         else k=Next_r[k];
    50     }
    51 }
    52 void GetNext_c()
    53 {
    54     int k=Next_c[0]=-1;
    55     int j=0;
    56     while(j<n)
    57     {
    58         if(k==-1||row[k]==row[j]) Next_c[++j]=++k;
    59         else k=Next_c[k];
    60     }
    61 }
    62 int main()
    63 {
    64     ios::sync_with_stdio(false);
    65     cin.tie(0);cout.tie(0);
    66     cin>>n>>m;
    67     for(int i=0;i<n;++i)
    68     {
    69         cin>>str[i];
    70         for(int j=0;j<m;++j)
    71         {
    72             row[i]=row[i]*Base+str[i][j];
    73             col[j]=col[j]*Base+str[i][j];
    74         }
    75     }
    76     
    77     GetNext_r();GetNext_c();
    78     cout<<(m-Next_r[m])*(n-Next_c[n])<<endl;
    79 }
    View Code

    I - Theme Section

    Next数组应用

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=1e6+5;
    28 string str;
    29 int N,Next[MAXN],len; 
    30 int read()
    31 {
    32     int s=1,x=0;
    33     char ch=getchar();
    34     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    35     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    36     return x*s;
    37 }
    38 void GetNext()
    39 {
    40     int k=Next[0]=-1;
    41     int j=0;
    42     while(j<len)
    43     {
    44         if(k==-1||str[j]==str[k]) Next[++j]=++k;
    45         else k=Next[k];
    46     }
    47 }
    48 void solve()
    49 {
    50     len=str.size();
    51     GetNext();
    52     if(Next[len]==0||len<=2) cout<<0<<endl;
    53     else
    54     {    
    55         int t=Next[len];
    56         bool flag=false;
    57         while(t&&!flag)
    58         {
    59             if(3*t>len) 
    60             {
    61                 t=Next[t];
    62                 continue;
    63             }
    64             for(int i=t+1;i<=len-t&&!flag;++i)
    65             if(Next[i]==t) flag=true;
    66             if(!flag) t=Next[t];
    67         }
    68         if(flag) cout<<t<<endl;
    69         else cout<<0<<endl;     
    70     } 
    71 }
    72 int main()
    73 {
    74     ios::sync_with_stdio(false);
    75     cin.tie(0);cout.tie(0);
    76     cin>>N;
    77     while(N--)
    78     {
    79         cin>>str;
    80         solve();
    81     }
    82     return 0;
    83 }
    View Code

    J - A Secret

    给定两个串S、T,求串T的每个后缀在串S中出现的次数与长度之积的和。

    用Exkmp要方便一点..

    https://blog.csdn.net/my_sunshine26/article/details/77991511

    再计一点,int最大值*int最大值不会爆long long,但要记得类型转换成long long

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 const int MAXN=1e6+5;
    28 const int MOD=1e9+7;
    29 string S,T;
    30 int lS,lT;
    31 int Next[MAXN],Extend[MAXN];
    32 void GetNext()
    33 {
    34     int a=0,p=0;
    35     Next[0]=lT;
    36     for(int i=1;i<lT;++i)
    37     {
    38         if(i>=p||i+Next[i-a]>=p)
    39         {
    40             if(i>=p) p=i;
    41             while(p<lT&&T[p]==T[p-i]) p++;
    42             Next[i]=p-i;
    43             a=i;
    44         }
    45         else Next[i]=Next[i-a];
    46     }
    47 }
    48 void GetExtend()
    49 {
    50     int a=0,p=0;
    51     GetNext();
    52     for(int i=0;i<lS;++i)
    53     {
    54         if(i>=p||i+Next[i-a]>=p)
    55         {
    56             if(i>=p) p=i;
    57             while(p<lS&&p-i<lT&&S[p]==T[p-i]) p++;
    58             Extend[i]=p-i;
    59             a=i;
    60         }
    61         else Extend[i]=Next[i-a];
    62     }
    63 }
    64 ll sum(int len)
    65 {
    66     return ((ll)len*((ll)len+1)/2)%MOD;
    67 }
    68 int main()
    69 {
    70     ios::sync_with_stdio(false);
    71     cin.tie(0);cout.tie(0);
    72     int test;cin>>test;
    73     while(test--)
    74     {
    75         cin>>S>>T;
    76         lS=S.size(),lT=T.size();
    77         reverse(S.begin(),S.end());
    78         reverse(T.begin(),T.end());
    79         GetExtend();
    80         ll ans=0;
    81         for(int i=0;i<lS;++i)
    82         {
    83             if(Extend[i]) 
    84             ans=(ans+sum(Extend[i]))%MOD;
    85         }
    86         cout<<ans<<endl;
    87     }
    88 }
    View Code

    K - Bazinga

    给定n个串,求最大的i,使得(1<=j<i)且Sj不是Si的子串。

    利用子串的传递性,当i是j的子串,j是k的子串时那么i也是k的子串

     1 #include<iostream>
     2 #include<cstring>
     3 #include<string>
     4 using namespace std;
     5 int son[555];
     6 string str[555];
     7 int Next[555][2222];
     8 void GetNext(int it,int len)
     9 {
    10     int k=Next[it][0]=-1;
    11     int j=0;
    12     while(j<len)
    13     {
    14         if(k==-1||str[it][j]==str[it][k]) Next[it][++j]=++k;
    15         else k=Next[it][k];
    16     }
    17 }
    18 bool kmp(int a,int b)//str_a is or not substring of str_b 
    19 {
    20     int m=str[a].size(),n=str[b].size();
    21     int i=0,j=0;
    22     while(i<n)
    23     {
    24         if(j==-1||str[b][i]==str[a][j]) ++i,++j;
    25         else j=Next[a][j];
    26         if(j==m) return true;
    27     }
    28     return false;
    29 }
    30 void solve(int n)
    31 {
    32     memset(son,-1,sizeof(son));
    33     for(int i=1;i<=n-1;++i)
    34     {
    35         GetNext(i,int(str[i].size()));
    36         if(kmp(i,i+1)) son[i]=1;
    37         else son[i]=0;
    38     }
    39     int ans=-1;
    40     for(int i=n;i>=2&&ans==-1;--i)
    41     for(int j=i-1;j>=1&&ans==-1;--j)
    42     if(!son[j]&&!kmp(j,i)) ans=i;
    43     cout<<ans<<endl;
    44 }
    45 int main()
    46 {
    47     ios::sync_with_stdio(false);
    48     cin.tie(0);cout.tie(0);
    49     int t,n;cin>>t;
    50     for(int test=1;test<=t;++test)
    51     {
    52         cout<<"Case #"<<test<<": ";
    53         cin>>n;
    54         for(int i=1;i<=n;++i)
    55         cin>>str[i];
    56         solve(n);
    57     }
    58 } 
    View Code

    L - Blue Jeans

     给定n个串求最大公共子串(串长度都为60)

    暴力。略

    M - Substring Frequency

    求一个串在令一个串中出现的次数。

    KMP模板题

     1 #include<iostream>
     2 #include<cstring>
     3 #include<string>
     4 using namespace std;
     5 const int MAXN=1e6+5;
     6 int Next[MAXN];
     7 string S,T;
     8 int lS,lT;
     9 void GetNext()
    10 {
    11     int k=Next[0]=-1;
    12     int j=0;
    13     while(j<lT)
    14     {
    15         if(k==-1||T[k]==T[j]) Next[++j]=++k;
    16         else k=Next[k];
    17     }
    18 }
    19 int kmp()
    20 {
    21     GetNext();
    22     int i=0,j=0,res=0;
    23     while(i<lS)
    24     {
    25         if(j==-1||S[i]==T[j]) ++i,++j;
    26         else j=Next[j];
    27         if(j==lT) res++,j=Next[j];
    28     }
    29     return res;
    30 }
    31 int main()
    32 {
    33     ios::sync_with_stdio(false);
    34     cin.tie(0);cout.tie(0);
    35     int test;cin>>test;
    36     for(int t=1;t<=test;++t)
    37     {
    38         cin>>S>>T;
    39         lS=S.size(),lT=T.size();
    40         cout<<"Case "<<t<<": "<<kmp()<<endl;
    41     }
    42     
    43 }
    View Code

    N - Making Huge Palindromes

    在一个串后添加任意字符使得该穿变为回文串,求添加的最少字符

    令原串为S,其反串为T,那么S+T一定是个回文串,要长度最小,就是求其重叠长度

     1 #include<iostream>
     2 #include<cstring>
     3 #include<string>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=1e6+5;
     7 int Next[MAXN];
     8 string S,T;
     9 int lS,lT;
    10 void GetNext()
    11 {
    12     int k=Next[0]=-1;
    13     int j=0;
    14     while(j<lT)
    15     {
    16         if(k==-1||T[k]==T[j]) Next[++j]=++k;
    17         else k=Next[k];
    18     }
    19 }
    20 int kmp()
    21 {
    22     GetNext();
    23     int i=0,j=0,res=0;
    24     while(i<lS)
    25     {
    26         if(j==-1||S[i]==T[j]) ++i,++j;
    27         else j=Next[j];
    28     }
    29     return j;
    30 }
    31 int main()
    32 {
    33     ios::sync_with_stdio(false);
    34     cin.tie(0);cout.tie(0);
    35     int test;cin>>test;
    36     for(int t=1;t<=test;++t)
    37     {
    38         cin>>S;
    39         T=S;
    40         reverse(T.begin(),T.end());
    41         lS=S.size(),lT=T.size();
    42         cout<<"Case "<<t<<": "<<2*lS-kmp()<<endl;
    43     }
    44     
    45 }
    View Code
  • 相关阅读:
    如何使用shell脚本快速排序和去重文件数据
    centos7下搭建git和gitlab版本库
    Jenkins安装部署
    那日了狗的上半年的兼容性问题,下半年来解决。
    RecyclerView notifyDataSetChanged不起作用
    android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出的解决办法
    java.lang.UnsatisfiedLinkError: Couldn't load hyphenate_av from loader dalvik.system.PathClassLoader
    android studio Error:java.lang.OutOfMemoryError: GC overhead limit exceeded
    apache https配置
    docker进入容器的方式
  • 原文地址:https://www.cnblogs.com/wangzhebufangqi/p/11357726.html
Copyright © 2011-2022 走看看