CF126B Password【KMP】By cellur925

题目传送门

其实$Chemist$在之前写了非常棒的题解

我长话短说,补充两句。

  • “那么当$next[n]$>$max$时显然不能将$next[n]$作为最长子串的长度”这句话其实在说,因为一个合法的串结尾肯定在2~$n$-1中,而$next[n]$的结尾在$n$处,显然是达不到的。那么我们就要继续缩小范围。直到存在合法串。
  • $next[n]$等于0时无解?根据$next$数组的含义,我们知道它连相同前缀和后缀的匹配不上(没有),何谈中间部分的子串?
  • 输出的时候找到合法的地点就结束程序,防止多输出东西。

$My$ $Code$

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 int len,j,maxx,tmp;
 8 int nxt[1000090];
 9 char a[1000090];
10 
11 int main()
12 {
13     scanf("%s",a+1);
14     len=strlen(a+1);
15     for(int i=2;i<=len;i++)
16     { 
17         while(j&&a[i]!=a[j+1]) j=nxt[j];
18         if(a[i]==a[j+1]) j++;
19         nxt[i]=j;
20         if(i!=len) maxx=max(maxx,nxt[i]);
21     }
22     if(!nxt[len]){printf("Just a legend");return 0;}
23     tmp=nxt[len];
24     while(tmp>maxx) tmp=nxt[tmp];
25     if(!tmp) {printf("Just a legend");return 0;}
26     for(int i=2;i<len;i++)
27         if(tmp==nxt[i])
28         {
29             for(int j=i-tmp+1;j<=i;j++)
30                 printf("%c",a[j]);
31             return 0;
32         }
33     return 0;
34 }
View Code

今天复习(学习)了下$KMP$算法,感觉这个算法最精妙的部分还是在$next$数组,而且体现了迭代的思想(?)“$j$=$next[j]$”,陌生的字符串问题可与$next$做类比,稍加改动进行求解。

另外欢迎大家资瓷文雀乐队新专辑《廟雨連珠》,链接藏在了这篇随笔的某个地方233.

posted @ 2018-10-03 23:25  cellur925&Chemist  阅读(175)  评论(0编辑  收藏  举报