标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4300
题意:说实话,看半天题目,愣是没看懂,百度题意才看懂,大概意思就是:第一个串串为匹配串,第i个代表字母顺序中的第i个,比如第一个是q,那么,q就代表a。
第二个串是密文+明文,密文全部都有,但明文可能不全,输出完整的密文+明文。
题解:有两种做法,第一种,用扩展KMP:
1.先把s2砍半,前面一半必定为密文,后面一半可能是密文+明文。
2.把前面的一半转化成明文。
3.用后面的和前面的找最长公共前缀,这个前缀必须到底,换句话说,找到的前缀必须到后一半的最后一个字符。
第二种,KMP:前面两部分一样,后面只是去找后缀匹配。
代码如下:
EXKMP:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=100010; //字符串长度最大值 7 /*next数组的作用:使得在求ex数组的时候成为线性的求法*/ 8 /*ex数组的作用:表示从i。。n的子串与匹配串的最长公共前缀*/ 9 char s1[30],s[30]; 10 char t[maxn]; 11 //ex数组即为extend数组 12 //预处理计算next数组 13 int Next[maxn],extand[maxn]; 14 char S[maxn],T[maxn]; 15 void GetNext(const char *T){ 16 int len=strlen(T),a=0; 17 Next[0]=len; 18 while(a<len-1 && T[a]==T[a+1]) a++; 19 Next[1]=a; 20 a=1; 21 for(int k=2;k<len;k++){ 22 int p=a+Next[a]-1,L=Next[k-a]; 23 if( (k-1)+L >= p){ 24 int j = (p-k+1)>0 ? (p-k+1) : 0; 25 while(k+j<len && T[k+j]==T[j]) j++; 26 Next[k]=j; 27 a=k; 28 } 29 else 30 Next[k]=L; 31 } 32 } 33 void GetExtand(const char *S,const char *T){ 34 GetNext(T); 35 int slen=strlen(S),tlen=strlen(T),a=0; 36 int MinLen = slen < tlen ? slen : tlen; 37 while(a<MinLen && S[a]==T[a]) a++; 38 extand[0]=a; 39 a=0; 40 for(int k=1;k<slen;k++){ 41 int p=a+extand[a]-1, L=Next[k-a]; 42 if( (k-1)+L >= p){ 43 int j= (p-k+1) > 0 ? (p-k+1) : 0; 44 while(k+j<slen && j<tlen && S[k+j]==T[j]) j++; 45 extand[k]=j; 46 a=k; 47 } 48 else 49 extand[k]=L; 50 } 51 } 52 53 int main() 54 { 55 int test; 56 cin>>test; 57 while(test--) 58 { 59 memset(S,0,sizeof(S)); 60 memset(T,0,sizeof(T)); 61 memset(s,0,sizeof(s)); 62 scanf("%s%s",s1,t); 63 for(int i=0;i<26;i++) 64 { 65 s[s1[i]-‘a‘]=i+‘a‘; 66 } 67 //cout<<s<<endl; 68 int len = strlen(t); 69 int mid; 70 if(len%2) 71 mid = len/2+1; 72 else 73 mid = len/2; 74 strcpy(S,t+mid); 75 for(int i=0;i<len;i++) 76 T[i]=s[t[i]-‘a‘]; 77 // cout<<S<<endl<<T<<endl; 78 GetExtand(S,T); 79 int llen = strlen(S); 80 int lllen= strlen(T); 81 int temp; 82 int mm=-1; 83 for(int i=0;i<llen;i++) 84 { //printf("%d ",extand[i]); 85 if(i+extand[i]+mid==lllen) 86 { 87 mm=extand[i]; 88 break; 89 } 90 } 91 // cout<<mm<<endl<<temp<<endl<<mid<<endl; 92 int mmm=len/2; 93 cout<<t; 94 if(mm==-1) 95 mm=0; 96 for(int i=mm;i<lllen-mm;i++) 97 { 98 printf("%c",T[i]); 99 } 100 cout<<endl; 101 } 102 }
KMP:
1 #include<iostream> 2 #include<string.h> 3 using namespace std; 4 char t[100006],s[100006],str1[26]; 5 int next[100006],str[1000]; 6 void getnext() 7 { 8 int i=0,j=-1; 9 next[0]=-1; 10 int len=strlen(s); 11 while(i<len) 12 { 13 if(j==-1||s[i]==s[j]) 14 { 15 i++; 16 j++; 17 next[i]=j; 18 } 19 else 20 j=next[j]; 21 } 22 } 23 int kmp() 24 { 25 int i,j=0; 26 int lent=strlen(t); 27 int lens=strlen(s); 28 if(lent%2==1) 29 i=lent/2+1; 30 else 31 i=lent/2; 32 while(i<lent&&j<lens) 33 { 34 if(j==-1||t[i]==s[j]) 35 { 36 i++; 37 j++; 38 } 39 else 40 j=next[j]; 41 } 42 return j; 43 } 44 int main() 45 { 46 int text; 47 scanf("%d",&text); 48 while(text--) 49 { 50 char ch; 51 int i; 52 scanf("%s",str1); 53 for(i=0;i<26;i++) 54 { 55 ch=str1[i]; 56 str[ch]=i; 57 } 58 scanf("%s",t); 59 int lent=strlen(t); 60 for(i=0;i<lent;i++) 61 { 62 int temp=str[t[i]]; 63 s[i]=temp+‘a‘; 64 } 65 getnext(); 66 int j=kmp(); 67 if(j*2==lent) 68 { 69 printf("%s\n",t); 70 } 71 else 72 { 73 int tmp1=lent-j; 74 printf("%s",t); 75 for(i=j;i<tmp1;i++) 76 printf("%c",s[i]); 77 printf("\n"); 78 } 79 } 80 return 0; 81 }
标签:
原文地址:http://www.cnblogs.com/ikids/p/4652595.html