• Password(KMP)


    传送门
    刚开始练KMP题目,自己好菜啊...
    这道题思路大致上对了,但是细节上出现了很大的偏差。
    问题在于对于回文串的情况没有想全,仅仅想到了非重复回文串如abcdeabc以及单一回文串aaaaaa,于是考虑了两种情况,但是还有一种就是重复非单一回文串,用我的思路直接是求出next数组,分情况讨论,对于非单一的肯定就一种情况,但是如果出现abcabcabc那么 next[n] 就会是6,而目标是用3来求,不仅如此还打算用扩展kmp,Z算法来求,于是这样就错了。

    看了题解才发现自己完全想多了,只需要在遍历中判断next[i]是否等于next[n]就可以了,这样就能保证是满足题意的,同时在求next数组中求出除了最后一位的next最大值,设其为maxn,有可能maxn是小于n的,那么这样就不满足条件如aaaaa,next[4] = 3 != next[5],所以要将长度缩小,也就是将首尾相同的串的长度缩小,直到小于等于这个中间最长串。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e6 + 10;
    char s[N];
    int ne[N], ne1[N], extend[N];
    int maxn = 0;
    int main(){
    	scanf("%s", s + 1);
    	int n = strlen(s + 1);
    	for(int i = 2, j = 0; i <= n; i ++){
    		while(j && s[i] != s[j + 1])
    			j = ne[j];
    		if(s[i] == s[j + 1])
    			j ++;
    		ne[i] = j;
    		if(i != n)
    			maxn = max(maxn, ne[i]);
    	}
    	if(ne[n] == 0){
    		cout << "Just a legend" << endl;
    		return 0;
    	}
    	int x = ne[n];
    	while(maxn < x)
    		x = ne[x];
    	if(x == 0){
    		cout << "Just a legend" << endl;
    		return 0;
    	}
    	for(int i = 2; i <= n - 1; i ++){
    		if(ne[i] == x){
    			for(int j = n - ne[i] + 1; j <= n; j ++){
    				printf("%c", s[j]);
    			}
    			return 0;
    		}
    	}
    	
    	//以下为废弃代码
    	/*string str, p;
    	p += "@";
    	for(int i = 2; i <= n - 1; i ++)
    		p += s[i];
    		
    	cout << ne[n] << endl;
    	if(ne[n] > 0 && s[1] != s[n]){
    		for(int i = n - ne[n] + 1; i <= n; i ++)
    			str += s[i];
    		str = "@" + str;
    		int len = ne[n];
    		for(int i = 2, j = 0; i <= n - 2; i ++){
    			while(j && p[i] != p[j + 1])
    				j = ne1[j];
    			if(p[i] == p[j + 1])
    				j ++;
    			ne1[i] = j;
    		}
    		for(int i = 2, j = 0; i <= n - 2; i ++){
    			while(p[i] != str[j + 1] && j)
    				j = ne1[j];
    			if(p[i] == str[j + 1])
    				j ++;
    			if(j == len){
    				for(int i = n - ne[n] + 1; i <= n; i ++)
    					printf("%c", s[i]);
    				return 0;
    			}
    		}
    		printf("Just a legend
    ");
    	}else if(ne[n] > 0 && s[1] == s[n]){
    		for(int i = n - ne[n] + 1; i <= n; i ++)
    			str += s[i];
    		int len = ne[n];
    		getExtend(p, str);
    		int maxn = -1;
    		for(int i = 1; i <= n - 2; i ++)
    			maxn = max(maxn, extend[i]);
    		for(int i = 1; i <= n; i ++)
    			cout << extend[i] << ' ';
    		cout << endl;
    		for(int i = n - maxn + 1; i <= n; i ++)
    			printf("%c", s[i]);
    	}
    	*/
    	
    	return 0;
    } 
    
  • 相关阅读:
    DevExpress中设置PanelControl背景的方法
    ArcEngine选中面要素样式修改
    DEV winform treelist设置背景图像
    React-Native运行知乎日报遇到的问题
    winform程序自动升级
    jquery图片轮播效果(unslider)
    Orchard搜索与索引
    网络版会飞的小鸟
    jQuery event的复制粘贴的坑
    记一次有趣的互联网事件及console.log~
  • 原文地址:https://www.cnblogs.com/pureayu/p/14806027.html
Copyright © 2020-2023  润新知