HDOJ A + B for you again 1867【KMP】



A + B for you again

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


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   |   We have carefully selected several similar problems for you:   1866  1277  1358  1753  1868 
 


题意:给定两个串。。要求组成一个最短的串。如果第一个串的后缀和第二个串的前缀相同时,可以删去一个前缀或后缀就可以。最重要的是要串最短,然后是要求是字典序最小的顺序输出。

解题思路:

一开始是想利用next存取前缀后缀最大匹配的方式做,把后面的串放前面,这样就变成求前缀后缀最大匹配,结果写完发现自己想的样例过不了,各种纠结。后来去网上找解题报告发现题意理解不完全。。。。而且发现这样想是不对的,如果是cbc  bcb 这样的最大前缀后缀后缀是4, 而题目并不是这个意思。所有,就要考虑加上KMP判断,找出最大的匹配位置就可以了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#define maxn 100000+10

using namespace std;

char P[maxn];
char S[maxn];

int pre[200010];

void getnext(char X[maxn],int xlen)
{
    int i=0,j=-1;
    pre[0]=-1;
    while(i<xlen){
        if(j==-1||X[i]==X[j]){
            i++;j++;
            if(X[j]!=X[i])
			pre[i]=j;
			else pre[i]=pre[j];
        }
        else j=pre[j];
    }
}

int kmpsearch(char *x,char *y)
{
	int i=0,j=0;
	int xlen=strlen(x);
	int ylen=strlen(y);	
	getnext(x,xlen);
	while(j<xlen&&i<ylen){
		if(j==-1||x[j]==y[i]){
			i++;j++;
		}
		else j=pre[j];
	}
	if(i>=ylen)return j;
	return 0;
}

int main()
{
    while(scanf("%s%s",P,S)!=EOF){
    	int l1=kmpsearch(P,S);
    	int l2=kmpsearch(S,P);
    	if(l1==l2){
    		if(strcmp(P,S)>0){
    			printf("%s%s\n",S,P+l1);
			}
			else printf("%s%s\n",P,S+l1);
		}
		else if(l1<l2){
			printf("%s%s\n",P,S+l2);
		}
		else{
			printf("%s%s\n",S,P+l1);
		}
    }
    return 0;
}

你可能感兴趣的:(HDOJ A + B for you again 1867【KMP】)