HDU 4300 Clairewd’s message(KMP+思维)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4300
题目大意:题目大意就是给以一段字符xxxxzzz前面x部分是密文z部分是明文,但是我们不知道是从哪里将密文和明文分开的,
密文是完整的,明文可能是不完整的,需要你补全,使得明文长度尽可能短。
解题思路:
因为密文至少占一半长度,所以从mid~len先假设为明文,然后将明文
转成密文求出nxt[len](nxt[len]<=len-nxt[eln],不断递归nxt[len]直到满足条件)即为明文长度。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=1e6+5; 7 8 int nxt[N]; 9 char s[30],pass[30],text[N];//s将明文转密文,pass将密文转明文 10 11 void getnext(char *p,int m){ 12 int i,j; 13 i=0,j=nxt[0]=-1; 14 while(i<m){ 15 while(j!=-1&&p[i]!=p[j]) 16 j=nxt[j]; 17 nxt[++i]=++j; 18 } 19 } 20 21 int main(){ 22 int t; 23 scanf("%d",&t); 24 while(t--){ 25 scanf("%s%s",s,text); 26 int len=strlen(text); 27 int mid=(len+1)/2; 28 for(int i=0;i<26;i++){ 29 pass[s[i]-'a']=i+'a'; 30 } 31 for(int i=mid;i<len;i++){ 32 text[i]=s[text[i]-'a']; 33 } 34 getnext(text,len); 35 int res=nxt[len]; 36 //明码长度res不能超过密码 37 while(res!=-1){ 38 if(res<=len-res) 39 break; 40 res=nxt[res]; 41 } 42 for(int i=mid;i<len;i++){ 43 text[i]=pass[text[i]-'a']; 44 } 45 printf("%s",text); 46 for(int i=res;i<len-res;i++){ 47 printf("%c",pass[text[i]-'a']); 48 } 49 puts(""); 50 } 51 return 0; 52 }