1. 程式人生 > >HDU1867 A + B for you again(KMP)

HDU1867 A + B for you again(KMP)

字典 不一定 string 連接 title pan log cst tail

A + B for you again

Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7978 Accepted Submission(s): 2005


Problem Description Generally speaking, there are a lot of problems about strings processing. Now you encounter another such problem. If you get two strings, such as “asdf” and “sdfg”, the result of the addition between them is “asdfg”, for “sdf” is the tail substring of “asdf” and the head substring of the “sdfg” . However, the result comes as “asdfghjk”, when you have to add “asdf” and “ghjk” and guarantee the shortest string first, then the minimum lexicographic second, the same rules for other additions.

Input For each case, there are two strings (the chars selected just form ‘a’ to ‘z’) for you, and each length of theirs won’t exceed 10^5 and won’t be empty.

Output Print the ultimate string by the book.

Sample Input asdf sdfg asdf ghjk

Sample Output asdfg asdfghjk

Author Wang Ye

Source 2008杭電集訓隊選拔賽——熱身賽

Recommend lcy 分析:合並的時候,一個字符串的後綴和另一個字符串的前綴的公共部分只計算一次,於是很容易想到KMP的Next數組的定義(前綴和後綴的最大匹配長度) 故可以把它們連接在一起(中間用‘#‘分割)求出Next數組,Next[len]就等於它們前綴和後綴的最大公共長度,然後就能生成它們合並後的字符串1. 因為題目中所給的兩個字符串誰在前,誰在後是不一定的, 所以再把題目中的兩個字符串顛倒再求一次,生成字符串2. 比較它們的長度和字典序,就能得出答案 代碼如下:
#include <cstdio>
#include 
<iostream> #include <cstring> using namespace std; const int N = 2e5+10; int Next[N]; char S[N], T[N]; char a[N],b[N]; char tmp[N]; char res1[N],res2[N]; int slen, tlen;//註意每次一定要計算長度 int alen,blen; int ans; int len1,len2; void getNext() { int j, k; j = 0; k = -1; Next[0] = -1; while(j < tlen) if(k == -1 || T[j] == T[k]) Next[++j] = ++k; else k = Next[k]; } int main() { while(scanf("%s%s",a,b)!=EOF){ alen=strlen(a); blen=strlen(b); for(int i=0;i<blen;i++) T[i]=b[i]; T[blen]=#; for(int i=0;i<alen;i++) T[blen+1+i]=a[i]; tlen=alen+blen+1; T[tlen]=0; getNext(); ans=Next[tlen]; for(int i=0;i<alen;i++) res1[i]=a[i]; for(int i=ans;i<blen;i++) res1[alen+i-ans]=b[i]; len1=alen+blen-ans; res1[len1]=0; memcpy(tmp,a,sizeof(a)); memcpy(a,b,sizeof(b)); memcpy(b,tmp,sizeof(tmp)); swap(alen,blen); for(int i=0;i<blen;i++) T[i]=b[i]; T[blen]=#; for(int i=0;i<alen;i++) T[blen+1+i]=a[i]; tlen=alen+blen+1; T[tlen]=0; getNext(); ans=Next[tlen]; for(int i=0;i<alen;i++) res2[i]=a[i]; for(int i=ans;i<blen;i++) res2[alen+i-ans]=b[i]; len2=alen+blen-ans; res2[len2]=0; if(len1<len2) printf("%s\n",res1); else if(len1>len2) printf("%s\n",res2); else { if(strcmp(res1,res2)<=0) printf("%s\n",res1); else printf("%s\n",res2); } } return 0; }

HDU1867 A + B for you again(KMP)