题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1841
题目有问题题、目有问题——代码1和代码3为什么不能过
题意:给你两个字符串,求解一个最短的字符串,两个字符串连接的时候相同的可以重叠
例如: “alba” 和“bacau”重叠在一起的最短串是 “albacau”。
我感觉这道题用KMP,求next数组就行,先将两个字符串连接起来(两种方法),然后求解next[len],当这个值大于len1或len2时,
继续求解next,最后用len-两个中最大的值,但是这样WA了,个人感觉没错,求解释。
WA代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
typedef __int64 LL;
const int N=1000005;
const LL II=1000000007;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
char word[2*N],s1[N],s2[N];
int len,next[2*N];
void getnext(char *p,int wlen)
{
int j=0,k=-1;
next[0]=-1;
while(j<wlen)
{
if(k==-1||p[j]==p[k])
{
j++; k++;
next[j]=k;
}
else
k=next[k];
}
}
int main()
{
int ca=0,i,j,T;
scanf("%d",&T);
while(T--)
{
int len1,len2,t1,t2;
scanf("%s%s",s1,s2);
len1=strlen(s1);
len2=strlen(s2);
len=len1+len2;
strcpy(word,s1);
strcat(word,s2);
word[len]='\0';
getnext(word,len);
t1=next[len];
while(t1>len1)
t1=next[t1];
strcpy(word,s2);
strcat(word,s1);
word[len]='\0';
getnext(word,len);
t2=next[len];
while(t2>len2)
t2=next[t2];
t1=max(t1,t2);
printf("%d\n",len-t1);
}
return 0;
}
看了别人的博客,发现在这个之前加上一个判断包含关系就过了,
我感觉我上面这个代码也可以判断包含关系啊。
求解释,吾当以身相许
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
typedef __int64 LL;
const int N=1000005;
const LL II=1000000007;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
char word[2*N],s1[N],s2[N];
int len,next[2*N];
void getnext(char *p,int wlen)
{
int j=0,k=-1;
next[0]=-1;
while(j<wlen)
{
if(k==-1||p[j]==p[k])
{
j++; k++;
next[j]=k;
}
else
k=next[k];
}
}
int kmp(char *text,char *word)
{
int i=0,j=0,k=0,wlen=strlen(word),tlen=strlen(text);
while(i<tlen)//i指向text,j指向word
{
if(j==-1||text[i]==word[j])
{ i++;j++; }
else
j=next[j]; // 当j=0时,next[j]=-1
if(j==wlen)
return tlen;
}
return 0;//检查text串中含有word串的个数
}
int main()
{
int ca=0,i,j,T;
scanf("%d",&T);
while(T--)
{
int len1,len2,t1,t2;
scanf("%s%s",s1,s2);
len1=strlen(s1);
len2=strlen(s2);
len=len1+len2;
if(len1>len2)
{
swap(len1,len2);
strcpy(word,s1);
strcpy(s1,s2);
strcpy(s2,word);
}
getnext(s1,len1);
int Min=kmp(s2,s1);
if(Min>0)
{
printf("%d\n",Min);
continue;
}
strcpy(word,s1);
strcat(word,s2);
word[len]='\0';
getnext(word,len);
t1=next[len];
while(t1>len1||t1>len2)
t1=next[t1];
strcpy(word,s2);
strcat(word,s1);
word[len]='\0';
getnext(word,len);
t2=next[len];
while(t2>len1||t2>len2)
t2=next[t2];
t1=max(t1,t2);
printf("%d\n",len-t1);
}
return 0;
}
又看了HDU1867,一模一样的,然后果断又改了一遍,提交,果断又WA了,
真心不知道哪里错了,哎………………悲催………………
WA代码:(感觉是对的)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;
typedef __int64 LL;
const int N=1000005;
const LL II=1000000007;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
char s1[N],s2[N];
int len,next[N];
void getnext(char *p,int wlen)
{
int j=0,k=-1;
next[0]=-1;
while(j<wlen)
{
if(k==-1||p[j]==p[k])
{
j++; k++;
next[j]=k;
}
else
k=next[k];
}
}
int kmp(char *text,char *word)
{
int i=0,j=0,tlen=strlen(text);
while(i<tlen)
{
if(j==-1||text[i]==word[j])
j++,i++;
else
j=next[j];
}
return j;
}
int main()
{
int ca=0,i,j,T;
cin>>T;
while(T--)
{
scanf("%s%s",s1,s2);
int len1,len2,t1,t2;
len1=strlen(s1);
len2=strlen(s2);
getnext(s2,len2);
t1=kmp(s1,s2);//s2模式串
getnext(s1,len1);
t2=kmp(s2,s1);//s1模式串
int len=len1+len2;
printf("%d %d\n",t1,t2);
if(t1==t2)
printf("%d\n",len-t1);
else
printf("%d\n",t1>t2?len-t1:len-t2);
}
return 0;
}