题目地址: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; }