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

A + B for you again KMP

A + B for you again

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


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........       給定兩個字串a和b,現在要將a和b相加,a+b相加規則為找出a最長的字尾等於b的等長字首,之後結果為a的前面部分+相等部分+b的後面部分,例如:asdf+sdfg=asdfg。相加的時候也可以b+a,輸出相加後長度最小的,若存在兩者長度相等,則輸出字典樹較小的(要用到strcmp
)。
用一個串匹配另一個串,被匹配串的最後的一位匹配值就是最長的相等部分了。然後用這種方法求得a+b和b+a,之後選擇小的輸出。



#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

const int maxn=1e5+10;
char a[maxn],b[maxn],c[maxn];
int f[maxn];
void GetNext(char *a,int *f,int n)
{
    int i,j;
    f[0]=f[1]=0;
    for(i=1;i<n;i++)
    {
        j=f[i];
        while(j&&a[i]!=a[j])j=f[j];
        f[i+1]=a[i]==a[j]?j+1:0;
    }
}
int KMP(char *a,char *b,int *f)
{
    int i,j=0,n,m;
    n=strlen(a);
    m=strlen(b);
    GetNext(b,f,m);
    for(i=0;i<n;i++)
    {
        while(j&&a[i]!=b[j])j=f[j];
        if(a[i]==b[j])j++;
    }
    return j;
}
int main()
{
    while(scanf("%s%s",a,b)!=EOF)
    {
        int i,j,k,p,q;
        p=KMP(a,b,f);
        q=KMP(b,a,f);
        if(p>q||p==q&&strcmp(a,b)<0) printf("%s%s\n",a,b+p);
        else printf("%s%s\n",b,a+q);
    }
    return 0;
}