类型:KMP
如:
题目:http://acm.timus.ru/problem.aspx?space=1&num=1684
思路:将amusing word看做模式串,将Jack's last word看做原串,进行匹配在kmp算法中如果更新到第一个字符都不匹配即可结束,输出"yes"
如果为"no",保存字符的匹配位置,从后往前更新每个前缀串到第一个字符如:
abracadabra
abrabracada
12342345678更新后为:
12312345678// ural 1684. Jack's Last Word
// wa ac 0.031s
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
using namespace std;
#define FOR(i,a,b) for(i = (a); i < (b); ++i)
#define FORE(i,a,b) for(i = (a); i <= (b); ++i)
#define FORD(i,a,b) for(i = (a); i > (b); --i)
#define FORDE(i,a,b) for(i = (a); i >= (b); --i)
#define CLR(a,b) memset(a,b,sizeof(a))
const int MAXN = 76010;
char st[MAXN], sp[MAXN];
int n, cnt, len, m;
int p[MAXN], endd[MAXN];
void next() {
int k = 0, i;
p[1] = 0;
FORE(i, 2, m) {
while(k > 0 && sp[i] != sp[k + 1])
k = p[k];
if(sp[k + 1] == sp[i])
k = k + 1;
p[i] = k;
}
}
int kmp() {
int k = 0, i;
FORE(i, 1, len) {
while(k > 0 && st[i] != sp[k + 1])
k = p[k];
if(k == 0 && st[i] != sp[k + 1])
return 1;
if(sp[k + 1] == st[i]) {
k = k + 1;
endd[i] = k;
}
}
return 0;
}
int main() {
int i;
scanf("%s %s", sp + 1, st + 1);
len = strlen(st + 1);
m = strlen(sp + 1);
next();
if(kmp() == 1)
cout<<"Yes\n";
else {
cout<<"No\n";
FORDE(i, len, 2) {
if(endd[i] == 1)
continue;
if(endd[i] - 1 != endd[i - 1])
endd[i - 1] = endd[i] - 1;
}
cout<<st[1];
FORE(i, 2, len) {
if(endd[i] == 1)
cout<<" ";
cout<<st[i];
}
cout<<endl;
}
return 0;
}