codeforces 1200 E. Compress Words(不同字符串最大前綴後綴相同長度)

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);
 
 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章