Tricky and Clever Passwordcsnd
来源:互联网 发布:seo怎么自学 编辑:程序博客网 时间:2024/05/16 23:44
一开始不懂什么是KMP算法,网上搜了一下,觉得这篇写得让我最能接受
http://www.ituring.com.cn/article/59881
我从里面摘抄了一些点子:
1.KMP算法优化字符串匹配的方法:寻找最长首尾匹配位置。
2.首尾匹配位置就是说,给定一个字符串N(长度为n,即N由N[0]...N[n]组成),找出是否存在这样的i,使得N[0]=N[n-i],N1=N[n-i-1],……,N[i]=N[n],不存在返回-1。
3.对于给定的字符串N,如何返回其最长首尾匹配位置?如abca,返回0,表示第0位与最后一位匹配;abcab,返回1,表示N[0,1]=N[n-1,n];abc,返回-1,表示没有首尾匹配,等等。
4.很好的简化:
5.kmp程序,其逻辑与 getnext()
函数(即前面寻找最长首位匹配函数)相同,因为都是在进行字符串匹配,只不过一个是匹配自身,一个是两个对比而已。
题目:
在年轻的时候,我们故事中的英雄——国王 Copa——他的私人数据并不是完全安全地隐蔽。对他来说是,这不可接受的。因此,他发明了一种密码,好记又难以破解。后来,他才知道这种密码是一个长度为奇数的回文串。
Copa 害怕忘记密码,所以他决定把密码写在一张纸上。他发现这样保存密码不安全,于是他决定按下述方法加密密码:他选定一个整数 X ,保证 X 不小于 0 ,且 2X 严格小于串长度。然后他把密码分成 3 段,最前面的 X 个字符为一段,最后面的 X 个字符为一段,剩余的字符为一段。不妨把这三段依次称之为 prefix, suffix, middle 。显然, middle 的长度为一个大于 0 的奇数,且 prefix 、 suffix 的长度相等。他加密后的密码即为 A + prefix + B + middle + C + suffix ,其中 A 、 B 、 C 是三个由 Copa 选定的字符串,且都有可能为空, + 表示字符串相连。
许多年过去了。Copa 昨天找到了当年写下加密后字符串的那张纸。但是,Copa 把原密码、A、B、C 都忘了。现在,他请你找一个尽量长的密码,使得这个密码有可能被当年的 Copa 发明、加密并写下。
起始位置 x_i 应该在 1 到加密后的字符串长度之间。 l_i 必须是正整数,因为你只要输出非空部分的信息。 middle 的长度必须为奇数。
如果有多组答案,任意一组即可。提示:你要最大化的是输出的 l_i 的总和,而不是 k 。
1 7
1 1
2 1
5 1
2 2
4 1
7 2
对于 30% 的数据: n <= 100
对于 100% 的数据: n <= 100000
存在 20% 的数据,输出文件第一行为 1 。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 100100#define MOD 999911657#define BASE 2333using namespace std;int n,ans;char s[M],rev_s[M];int next[M],f[M],pos[M];pair<int,int> intervals[M];int log_2[M],a[M][17],_ans[M];void KMP(){ int i,fix=0;//fix匹配成功的个数 for(i=2;i<=n;i++) //模式值数组的求取 { while( fix && rev_s[fix+1]!=rev_s[i] ) fix=next[fix]; if( rev_s[fix+1]==rev_s[i] ) ++fix; next[i]=fix; } fix=0;//KMP匹配——rev_s和s匹配 for(i=1;i<=n;i++) { while( fix && rev_s[fix+1]!=s[i] ) fix=next[fix]; if( rev_s[fix+1]==s[i] ) ++fix; if( i+fix>=n ) return ; if(!pos[fix]) { pos[fix]=i; intervals[fix]=make_pair(i+1,n-fix); } }}void Manacher(){ int i,id=1,mx=1; s[0]='$'; for(i=1;i<=n;i++) { f[i]=min(mx-i+1,f[id+id-i]); while(s[i+f[i]]==s[i-f[i]]) ++f[i]; if(i+f[i]-1>mx) mx=i+f[i]-1,id=i; }}int Get_Max(int x,int y){ int len=log_2[y-x+1]; return max(a[x][len],a[y-(1<<len)+1][len]);}int Bisection(int x,int y){ int l=1,r=y-x+2>>1; while(l+1<r) { int mid=l+r>>1; if( Get_Max(x+mid-1,y-mid+1)>=mid ) l=mid; else r=mid; } return Get_Max(x+r-1,y-r+1)>=r?r:l;}int main(){ int i,j; scanf("%s",s+1);n=strlen(s+1); for(i=1;i<=n;i++) //翻转s,存放在rev_s里面 rev_s[i]=s[n-i+1]; KMP(); Manacher(); pos[0]=1;intervals[0]=make_pair(1,n); for(i=2;i<=n;i++) log_2[i]=log_2[i>>1]+1;//i>>1——i/2 for(i=1;i<=n;i++) a[i][0]=f[i]; for(j=1;j<=log_2[n];j++) for(i=1;i+(1<<j)-1<=n;i++) a[i][j]=max(a[i][j-1],a[i+(1<<j-1)][j-1]);//左移n位,相当于乘以2^n; for(i=0;pos[i];i++) { _ans[i]=2*Bisection(intervals[i].first,intervals[i].second)-1; if(i*2+_ans[i]>ans*2+_ans[ans]) ans=i; } if(ans==0) { cout<<1<<endl; for(i=1;i<=n;i++) if(f[i]*2-1==_ans[0]) { cout<<i-f[i]+1<<' '<<_ans[0]<<endl; return 0; } } else { cout<<3<<endl; cout<<pos[ans]-ans+1<<' '<<ans<<endl; int l=intervals[ans].first,r=intervals[ans].second; for(i=l;i<=r;i++) if( min(min(i-l,r-i)+1,f[i])*2-1==_ans[ans] ) { cout<<i-(_ans[ans]>>1)<<' '<<_ans[ans]<<endl; break; } cout<<n-ans+1<<' '<<ans<<endl; } return 0;}
- Tricky and Clever Passwordcsnd
- 蓝桥杯-Tricky and Clever Password(java)
- CodeForces 30E Tricky and Clever Password(hash+manacher)
- codeforces #30E Tricky and Clever Password KMP+Manacher+二分
- codeforces 30E 蓝桥杯 Tricky and Clever Password
- Tricky and Clever Password 【KMP+Manacher】【蓝桥杯试题】
- 算法练习——Tricky and Clever Password
- Codeforces 30E Tricky and Clever Password Manacher + KMP + 前缀和
- 算法笔记_055-蓝桥杯练习 Tricky and Clever Password (Java)
- 算法笔记_055-蓝桥杯练习 Tricky and Clever Password (Java)
- 算法笔记_055-蓝桥杯练习 Tricky and Clever Password (Java)
- tricky
- Designing for Interaction: Creating Smart Applications and Clever Devices
- Top 10 tricky Java interview questions and answers
- RestClient(Restsharp) ContentType setting and HttpBaseAuth setting tricky.
- Powershell Tricky
- Excel Tricky
- Tricky Problems
- UVA 122 Trees on the level 二叉树层次遍历 数组&指针
- C++ 私有构造函数的作用
- HTTP协议之GET PUT POST DELETE方法
- [MySQL] 怎样使用Mysqlcheck来检查和修复, 优化表
- POST 和GET传输的最大容量分别是多少?
- Tricky and Clever Passwordcsnd
- [DP] Codeforces 687C #360 (Div. 1) C. The Values You Can Make
- 简单分析view.inflater和LaoutInflater的区别
- 产品经理职能类型
- 团体程序设计天梯赛-练习集 L3-001. 凑零钱 强行dfs+剪枝 解题报告
- C++动态二维对象数组
- Java基础知识
- 数据结构绪论
- c++ assert() 使用方法