1. 程式人生 > >hdoj 1867 A + B for you again【kmp,字首與字尾的匹配】

hdoj 1867 A + B for you again【kmp,字首與字尾的匹配】

A + B for you again

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
   
  
 
    
  
 

題目大意:輸入兩個字串啊a和b,然後把兩個字串收尾相連,相連時候,把a的字尾和b的字首重合【b的字尾和a的字首重合】,還要求輸出的合併字串字典序最小且長度最短。

思路:首先比較兩個字串的長度,若一樣長,則比較兩個字串的字典序,字典序小的放前面,

        然後再計算a的字尾和b的字首的匹配長度len1,接著計算b的字尾和a的字首的匹配長度len2,如果len1<len2,則b在前,a在後;否則,a在前,b在後。

Accept程式碼【C++】【46MS】【2300K】

#include <cstdio>
#include <cstring>

using namespace std;

char str_1[100001], str_2[100001];
int p[100001];
int total;

void Kmp_huan(char *k, int len) {
    int i = 0, j = -1;
    p[0] = -1;
    while(i + 1 < len) {
        if(j == -1 || k[i] == k[j]) {
        	i++, j++;
        	if(k[i] == k[j])
        		p[i] = p[j];
        	else
        		p[i] = j;//優化,即資料結構書中求的nextval陣列【http://blog.csdn.net/nailnehc/article/details/49184599】
		}
        else
            j = p[j];
    }
}

int KMP(char *s, char *t, int len_s, int len_t) {
    int i = 0, j = 0;
    memset(p, 0, sizeof(p));
    Kmp_huan(t, len_t);
    while(i < len_s){ 
        while(s[i] != t[j]) {
        	if(p[j] == -1) {
        		j = 0;
        		break;
			}
			j = p[j];
		}
		if(s[i] == t[j])
			j++;
		i++;
    }
	return j;
}

int main() {
    int x = 0, y = 0;
    int len_1, len_2;
    while(~scanf("%s %s", str_1, str_2)) {//筆者在這裡吃了癟,注意哈<---------  看過來 本來是【while(1) {   scanf()...   }】Output Limit Exceeded
        len_1 = strlen(str_1);
        len_2 = strlen(str_2);
        x = KMP(str_1, str_2, len_1, len_2);
        y = KMP(str_2, str_1, len_2, len_1);
        if(x == y) {
            if(strcmp(str_1, str_2) > 0) {
                printf("%s", str_2);
                printf("%s\n", str_1 + y);
            }
            else {
                printf("%s", str_1);
                printf("%s\n", str_2 + y);
            }
        }
        else if(x > y){
            printf("%s", str_1);
            printf("%s\n", str_2 + x);
        }
        else {
            printf("%s", str_2);
            printf("%s\n", str_1 + y);
        }
    }
    return 0;
}