[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\n",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<<"\n";
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])<<"\n";
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<<"\n";//已经是循环串 
53     else 
54     {
55         int T=len-Next[len];//最小循环节长度
56         cout<<(len/T+1)*T-len<<"\n"; 
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

 

转载于:https://www.cnblogs.com/wangzhebufangqi/p/11357726.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值