https://codeforces.com/contest/1200/problem/E
題意:給出n個單詞,可以把每個單詞前綴後綴相同的部分合並,求最後合併單詞
kmp模板題… 比賽的時候自己沒有模板,網上隨便找了個模板,改到最後tle,沒有時間了,原因還是因爲記不清楚kmp算法了,通過這道題複習了下。
思路:從第二個開始字符串開始和前面合併的子串進行kmp算法
注意每次匹配的起點位置,應該爲 文本串長度-模式串長度
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define fi first
#define se second
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 1e17 + 10;
const int N = 1e6 + 100;
const ll mod = 10007;
const int base=131;
tr1::unordered_map<ll,ll> mp;
char a[N],b[N],ans[N];
int nx[N];
int n, m;
int l1,l2;
void getnext(){
int k = -1, j = 0;
nx[0] = -1;
while(j < m){
if(k == -1 || b[j] == b[k]) nx[++j] = ++k;
else k = nx[k];
}
}
int KMP(int st)
{
int i,j;
getnext();
for(i=st,j=0;i<n;i++)
{
while(j>0&&b[j]!=a[i]) j=nx[j];//匹配不成功 跳轉到nx
if(a[i]==b[j]) j++;
if(j==m) return m;
}
return j;
}
int main()
{
int t;
scanf("%d",&t);
scanf("%s",a);
n=strlen(a);
t--;
int pos=0;
for(int i=1;i<=t;i++)
{
scanf("%s",b);
m=strlen(b);
int x=KMP(max(pos-m,0));
//show2(i,x)
for(int i=x;i<m;i++)
{
a[n++]=b[i];
}
pos=n;
}
a[n]='\0';
printf("%s\n",a);
}