题目链接:https://codeforc.es/contest/1200/problem/E
题意:
有n串字符串,让你连起来:sample please ease in out ---》 sampleaseinout
思路:
肯定KMP啊,但是比赛的时候对kmp的next数组一知半解,所以也不知道怎么用。
next数组其实就是对key串进行处理next(失配值),然后在母串上去匹配。
1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
2 #include <cstdio>//sprintf islower isupper
3 #include <cstdlib>//malloc exit strcat itoa system("cls")
4 #include <iostream>//pair
5 #include <fstream>
6 #include <bitset>
7 //#include <map>
8 //#include<unordered_map> https://codeforc.es/contest/1200/problem/E
9 #include <vector>
10 #include <stack>
11 #include <set>
12 #include <string.h>//strstr substr
13 #include <string>
14 #include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
15 #include <cmath>
16 #include <deque>
17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
18 #include <vector>//emplace_back
19 //#include <math.h>
20 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
21 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
22 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
23 #define fo(a,b,c) for(register int a=b;a<=c;++a)
24 #define fr(a,b,c) for(register int a=b;a>=c;--a)
25 #define mem(a,b) memset(a,b,sizeof(a))
26 #define pr printf
27 #define sc scanf
28 #define ls rt<<1
29 #define rs rt<<1|1
30 void swapp(int &a,int &b);
31 double fabss(double a);
32 int maxx(int a,int b);
33 int minn(int a,int b);
34 int Del_bit_1(int n);
35 int lowbit(int n);
36 int abss(int a);
37 //const long long INF=(1LL<<60);
38 const double E=2.718281828;
39 const double PI=acos(-1.0);
40 const int inf=(1<<29);
41 const double ESP=1e-9;
42 const int mod=(int)1e9+7;
43 const int N=(int)1e7+10;
44
45 int nxt[N],tlen,klen;
46 char key[N],txt[N];
47
48 void getNext()
49 {
50 int j,k;
51 j=0;
52 k=-1;
53 nxt[0]=-1;
54 while(j<klen)
55 {
56 if(k==-1||key[j]==key[k])
57 {
58 nxt[++j]=++k;
59 if(key[j]!=key[k])//优化
60 nxt[j]=k;
61 }
62 else
63 k=nxt[k];
64 }
65 }
66
67 int kmp()
68 {
69 int i=max(tlen-klen,0),j=0;//这边的 i 由于是算前后最大匹配长度所以只需要从后面的 key 长度的段开始就行了;
70 getNext();
71 while(i<tlen)//以母串结束而告终;
72 {
73 if(j==-1||txt[i]==key[j])
74 {
75 i++;
76 j++;
77 }
78 else
79 j=nxt[j];
80 }
81 return j;//出来的 j 就是 i 到结尾到时候的最大匹配长度;
82 }
83
84 int main()
85 {
86 int n;
87 sc("%d",&n);
88 sc("%s",txt);
89 tlen=strlen(txt);
90 fo(i,2,n)
91 {
92 sc("%s",key);
93 klen=strlen(key);
94 int pos=kmp();
95 fo(j,pos,klen-1)
96 txt[tlen++]=key[j];
97 }
98 txt[tlen]='\0';
99 pr("%s\n",txt);
100 return 0;
101 }
102
103 /**************************************************************************************/
104
105 int maxx(int a,int b)
106 {
107 return a>b?a:b;
108 }
109
110 void swapp(int &a,int &b)
111 {
112 a^=b^=a^=b;
113 }
114
115 int lowbit(int n)
116 {
117 return n&(-n);
118 }
119
120 int Del_bit_1(int n)
121 {
122 return n&(n-1);
123 }
124
125 int abss(int a)
126 {
127 return a>0?a:-a;
128 }
129
130 double fabss(double a)
131 {
132 return a>0?a:-a;
133 }
134
135 int minn(int a,int b)
136 {
137 return a<b?a:b;
138 }