Passward 题解
Passward
password.in/.out
你来到了一个庙前,庙牌上有一个仅包含小写字母的字符串 s。
传说打开庙门的密码是这个字符串的一个子串 t,并且 t 既是 s 的前缀又是 s 的后缀并且还在 s 的中间位置出现过一次。
如果存在这样的串,请你输出这个串,如有多个满足条件的串,输出最长的那一个。
如果不存在这样的串,输出"Just a legend"(去掉引号)。
输入格式:
仅一行,字符串 s。
输出格式:
如题所述
样例输入
fixprefixsuffix
样例输出:
fix
数据范围:
对于 60%的数据, s 的长度<=100
对于 100%的数据, s 的长度<=100000
solution:
这个题绝对是今天联考中最水的一道题了,一开始傻不愣登的忘了kmp怎么打了,直接上暴力连hash都没打,后来还是不会就打的hash,10^5的数据竟然过了,只能说数据太水。
hash:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define sushu 23333 8 char s[100005]; 9 int len=0; 10 void read() { 11 char ch=getchar(); 12 while(ch<'a'||ch>'z') { 13 ch=getchar(); 14 } 15 while(ch>='a'&&ch<='z') { 16 s[++len]=ch; 17 ch=getchar(); 18 } 19 return ; 20 } 21 unsigned long long hhsh[100005],kk[100005]; 22 unsigned long long get(int l,int r) { 23 return (hhsh[r]-hhsh[l-1]*kk[r-l+1]); 24 } 25 int main() { 26 read(); 27 hhsh[0]=1; 28 kk[0]=1; 29 for(int i=1; i<=len; i++) { 30 hhsh[i]=hhsh[i-1]*sushu+s[i]; 31 kk[i]=kk[i-1]*sushu; 32 } 33 int ans=0; 34 for(int i=len-1; i>=1; i--) { 35 int zuoyi=1,youyi=zuoyi+i-1; 36 int youer=len,zuoer=youer-i+1; 37 unsigned long long se=get(zuoyi,youyi),we=get(zuoer,youer); 38 if(se==we) { 39 for(int j=2; j+i-1<len; j++) { 40 int zuosan=j,yousan=j+i-1; 41 if(get(zuosan,yousan)==se) { 42 ans=i; 43 break; 44 } 45 } 46 if(ans) { 47 break; 48 } 49 } 50 } 51 if(ans) { 52 for(int i=1; i<=ans; i++) { 53 cout<<s[i]; 54 } 55 } else { 56 cout<<"Just a legend"; 57 } 58 return 0; 59 }
kmp:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 char s[100005]; 7 int fail[100005],n; 8 void GETFAIL() { 9 n=strlen(s); 10 fail[0]=fail[1]=0; 11 for(int i=2,k=0; i<=n; ++i) { 12 while(k&&s[k]!=s[i-1]) { 13 k=fail[k]; 14 } 15 if(s[k]==s[i-1]) { 16 ++k; 17 } 18 fail[i]=k; 19 } 20 } 21 int main() { 22 scanf("%s",s); 23 GETFAIL(); 24 int ji=n,ans; 25 bool pd=0; 26 while(fail[ji]) { 27 ans=0; 28 int len=fail[ji]; 29 for(int i=1,j=0; i<n-1; ++i) { 30 while(j&&s[j]!=s[i]) { 31 j=fail[j]; 32 } 33 if(s[j]==s[i]) { 34 ++j; 35 } 36 if(j==len) { 37 ++ans; 38 } 39 } 40 if(ans) { 41 pd=1; 42 break; 43 } 44 ji=fail[ji]; 45 } 46 if(pd) { 47 for(int i=0; i<fail[ji]; i++) { 48 cout<<s[i]; 49 } 50 } else { 51 cout<<"Just a legend"; 52 } 53 return 0; 54 }