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 }

 

posted @ 2017-08-07 19:31  Forever_goodboy  阅读(350)  评论(0编辑  收藏  举报