码迷,mamicode.com
首页 > 其他好文 > 详细

名校联赛DAY.2A层第一题passward题解

时间:2017-08-07 22:28:23      阅读:326      评论:0      收藏:0      [点我收藏+]

标签:相等   efi   描述   字符   bsp   mat   传说   turn   int   

问题 A: Passward

时间限制: 1 Sec  内存限制: 512 MB

题目描述

你来到了一个庙前,庙牌上有一个仅包含小写字母的字符串 s。

传说打开庙门的密码是这个字符串的一个子串 t,并且 t 既是 s 的前缀又是 s的后缀并且还在 s 的中间位置出现过一次。

如果存在这样的串,请你输出这个串,如有多个满足条件的串,输出最长的那一个。

如果不存在这样的串,输出"Just a legend"(去掉引号)。

输入格式:

仅一行,字符串 s。

输出格式:

如题所述

样例输入

fixprefixsuffix

样例输出:

fix

数据范围:

对于 60%的数据, s 的长度<=100

对于 100%的数据, s 的长度<=100000

  不得不说一下,这道题真的挺水的,当时考试时就是奔60分去的,谁知道一不小心满分了,数据水,不卡我。

  他们说这是KMP裸题,我当时也想到了这点,然而上次打KMP还是在一个半月前,有点忘,不敢直接打KMP,因此直接去打的HASH+MP(fail数组)+链表的暴力。

  首先先预处理出hash,mp的fail,链表,因为与前缀后缀相等的单词第一个字母一定和首字母相同,因此我们大可对与首字母相同的位置建一个链表,暴力撸一遍即可,真的挺无聊的。

  

技术分享
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<map>
 9 #include<cmath>
10 using namespace std;
11 char s[100005];
12 int n,a[100005];
13 int p=12345;
14 unsigned long long xp[100005];
15 map<int,unsigned long long> ha;
16 int hz[100005],qz[100005],fl[100005];
17 int main(){
18     scanf("%s",s);
19     n=strlen(s);
20     for(int i=0;i<n;i++)
21     {
22         a[i+1]=s[i]-a+1;
23     }
24     xp[0]=1;
25     for(int i=1;i<=n+2;i++)
26         xp[i]=xp[i-1]*p;
27     for(int i=n;i>0;i--)
28         ha[i]=ha[i+1]*p+a[i];
29     int nw=1;
30     for(int i=2;i<=n;i++)
31     {
32         if(a[i]==a[1])
33         {
34             hz[nw]=i;
35             qz[i]=nw;
36             nw=i;
37         }
38     }
39     for(int i=2,j=0;i<=n;i++)
40     {
41         while(j&&a[i]!=a[j+1]) j=fl[j];
42         if(a[i]==a[j+1]) j++;
43         fl[i]=j;
44     }
45     nw=n-fl[n]+1;
46     int ans=0;
47     while(nw)
48     {
49          
50         int l=n-nw+1;
51         unsigned long long hs=ha[1]-ha[l+1]*xp[l];
52         unsigned long long hss=ha[nw]-ha[n+1]*xp[l];
53         if(hs!=hss)
54         {
55             nw=hz[nw];
56             continue;
57         }
58         bool yx=1;
59          
60         for(int i=hz[1];i<nw;i=hz[i])
61         {
62             unsigned long long hh=ha[i]-ha[i+l]*xp[l];
63             if(hh==hs)
64             {
65                 ans=l;
66                 yx=0;
67                 break;
68             }
69         }
70         if(!yx)
71             break;
72         nw=hz[nw];
73     }
74     if(nw)
75     {
76         for(int i=0;i<ans;i++)
77             cout<<s[i];
78     }
79     else
80     {
81         printf("Just a legend\n");
82     }
83 //  while(1);
84     return 0;
85 }
View Code

 

名校联赛DAY.2A层第一题passward题解

标签:相等   efi   描述   字符   bsp   mat   传说   turn   int   

原文地址:http://www.cnblogs.com/liutianrui/p/7300985.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!