HDU 1867 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): 4496    Accepted Submission(s): 1157

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

题意讲解: 给你两个字符串 s1,s2让你把它们,连接起来前后相同的重合一起,不再输出;

连接规则:

假设     s1 + s2  能匹配的长度为 len1 ;

s2 + s1 能匹配的长度为  len2 ;

如果 len1 = len2 判断谁在前就要看谁得字典序小了,当然小的在前

如果 len1 > len2   输出匹配后的字符串 s1+s2

如果 len1 < len2   输出匹配后的字符串 s2+s1

所以AC代码如下:略长

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<queue>
  6 #include<string>
  7 #include<cmath>
  8 using namespace std;
  9 const int N = 1e5+10;
 10 char s1[N],s2[N];
 11 int next[2][N],len1,len2;
 12 int x1,x2;
 13 void solve1(int len1)//寻找第一个字符串的next数组
 14 {
 15     int i = 0;
 16     int j = -1;
 17     next[0][0] = -1;
 18     while(i<len1)
 19     {
 20         if(j== -1 || s1[i] == s1[j])
 21         {
 22             ++i;
 23             ++j;
 24             next[0][i] = j;
 25         }
 26         else
 27             {
 28                j = next[0][j];
 29             }
 30     }
 31 }
 32 void solve2(int len2)//寻找第二个字符串的next数组
 33 {
 34     int i = 0;
 35     int j = -1;
 36     next[1][0] = -1;
 37     while(i<len2)
 38     {
 39         if(j== -1 || s2[i] == s2[j])
 40         {
 41             ++i;
 42             ++j;
 43             next[1][i] = j;
 44         }
 45         else
 46             {
 47                j = next[1][j];
 48             }
 49     }
 50 }
 51 int solve(char *s3,char *s4,int len,int x) //xx:表示字符串s3和s4匹配时,是从s3的第xx个开始匹配的
 52 {
 53     int j=0,i=0;
 54     int  xx=0;
 55       while(i<len)
 56         {
 57              if(j==-1 || s3[i] == s4[j])
 58              {
 59                  i++;
 60                  j++;
 61              }
 62              else
 63              {
 64                 j = next[x][j];
 65                 xx=i-j;
 66              }
 67         }
 68         return xx;
 69 }
 70 int main()
 71 {
 72     while(~scanf("%s %s",s1,s2))
 73     {
 74         memset(next,-1,sizeof(next));
 75         len1 = strlen(s1);
 76         len2 = strlen(s2);
 77         solve1(len1);
 78         solve2(len2);
 79         int x1 = solve(s1,s2,len1,1);
 80         int x2 = solve(s2,s1,len2,0);
 81         //判断能匹配字符串的长度
 82         int xx1 = len1 - x1;
 83         int xx2 = len2 - x2;
 84         //当s1在前或者s2在前连接的字符串总长度是相同的,则要按照字典序小的在前,
 85         //例如:s1:abcefg s2:efgabc  都能匹配对方三个,所以要按照字典序abcefg 在前;
 86         if(xx1 == xx2)
 87         {
 88             if(strcmp(s1,s2)<0)
 89             {
 90                 for(int i=0; i<x1; i++)
 91                        printf("%c",s1[i]);
 92                   printf("%s\n",s2);
 93             }
 94             else
 95             {
 96                    for(int i=0; i<x2; i++)
 97                        printf("%c",s2[i]);
 98                   printf("%s\n",s1);
 99             }
100         }
101         //接下来就看,谁能匹配谁的多了,xx1 表示s2匹配s1 的长度,xx2表示  s1 匹配 s2的长度;
102         //例如s1: abcdef s2: hjabcd  ;这时s2,在前先输出;反之s1在前;
103        else if(xx1 > xx2)
104         {
105                for(int i=0; i<x1; i++)
106                 printf("%c",s1[i]);
107                printf("%s\n",s2);
108
109         }
110         else
111         {
112                     for(int i=0; i<x2; i++)
113                        printf("%c",s2[i]);
114                   printf("%s\n",s1);
115         }
116     }
117   return 0;
118 }
时间: 2024-10-06 15:49:29

HDU 1867 A + B for you again(KMP算法的应用)的相关文章

HDU 1867 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): 4636    Accepted Submission(s): 1193 Problem Description Generally speaking, there are a lot of problems about strings proces

HDU 1867 A + B for you again ----KMP

题意: 给你两个字符串,输出他们合并之后的字符串,合并的时候把A的后缀和B的前缀重叠合(或者把A的前缀和B的后缀重合).要求合并后的串既包含A右包含B,且使得合并后的字符串尽量短,其次是使得合并后的字符串字典序尽量小. 分析: 首先A和B合并他们一定是首尾重叠相连,要求合并后字典序最小,所以当合并后串长度一样时,我们要把A或B中字典序小的放在前面. 然后计算A的后缀和B的前缀匹配长度为len1,计算A的前缀和B的后缀匹配长度为len2. 如果len1大,那么就把A放前面.如果len2大,那么就把

HDU 1867 A + B for you again KMP题解

本题又是一个典型的KMP应用. 求两个字符串相加的结果,相加的规律是一个字符串的后缀和另一个字符串的前缀相同,就可以合并这个部分. 不过本题的题意不是很清晰,因为没有太明确指出这两个字符串的出现顺序是无关的,只是需要输出合并后长度最短的结果,如果合并后长度一样,那么就按照字典顺序,输出字典顺序在前的字符串. 思路: 1 使用kmp在s2查找s1,那么最终结束的时候next table的值就是s1前缀和s2的后缀相同的最长的长度了. 2 输入两个字符串s1和s2,那么就可以在s2中查找s1,得到长

hdu 1867 A + B for you again

题目: 链接:点击打开链接 题意: 找出两个字符串的后缀和前缀公共串,输出最短的串,并且为最小字典序. 算法: KMP算法. 思路: 取最小字典序输出... 代码: #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXN 100010 char s1[MAXN],s2[MAXN]; int next[MAXN]; void get_nextval(ch

HDU 1711 Number Sequence(KMP算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15548    Accepted Submission(s): 6836 Problem Description Given two sequence

KMP算法的定义及KMP练手题 HDU 1711 Number Sequence (我的模板代码)

题意:就是要你来找出b数组在a数组中最先匹配的位置,如果没有则输出-1 思路:直接KMP算法(算法具体思想这位牛写的不错http://blog.csdn.net/v_july_v/article/details/7041827) AC代码: #include<cstdio> #include<cstring> #include<stdlib.h> #include<iostream> using namespace std; #define maxn 100

HDU 2594 Simpsons’ Hidden Talents (字符串-KMP)

Simpsons' Hidden Talents Problem Description Homer: Marge, I just figured out a way to discover some of the talents we weren't aware we had. Marge: Yeah, what is it? Homer: Take me for example. I want to find out if I have a talent in politics, OK? M

hdu 1711 KMP算法模板题

题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串长度". 当发生失配的情况下,j的新值next[j]取决于模式串中T[0 ~ j-1]中前缀和后缀相等部分的长度, 而且next[j]恰好等于这个最大长度. 防止超时.注意一些细节.. 另外:尽量少用strlen.变量记录下来使用比較好,用字符数组而不用string //KMP算法模板题 //hdu

hdu 2594 java实现字符串KMP算法

Problem Description Homer: Marge, I just figured out a way to discover some of the talents we weren't aware we had. Marge: Yeah, what is it? Homer: Take me for example. I want to find out if I have a talent in politics, OK? Marge: OK. Homer: So I tak

HDU 4300 Clairewd’s message(初遇拓展KMP)

昨晚一不小心学了拓展KMP,被虐了一晚,最终是这份资料救了我...http://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html 说得简单易懂. 然后学了kuangbin的模版: /* * 扩展KMP算法 */ //next[i]:x[i...m-1]与x[0...m-1]的最长公共前缀 //extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀 void pre_EKMP(char x[],int m,int next[