HDU3374 String Problem(kmp,最大最小表示法)
来源:互联网 发布:kingroot是什么软件 编辑:程序博客网 时间:2024/05/16 17:34
Problem Description
Give you a string with length N, you can generate N strings by left
shifts. For example let consider the string “SKYLONG”, we can generate
seven strings: String Rank SKYLONG 1 KYLONGS 2 YLONGSK 3 LONGSKY 4
ONGSKYL 5 NGSKYLO 6 GSKYLON 7 and lexicographically first of them is
GSKYLON, lexicographically last is YLONGSK, both of them appear only
once. Your task is easy, calculate the lexicographically fisrt
string’s Rank (if there are multiple answers, choose the smallest
one), its times, lexicographically last string’s Rank (if there are
multiple answers, choose the smallest one), and its times also.
Input
Each line contains one line the string S with length N (N <=
1000000) formed by lower case letters.
Output
Output four integers separated by one space, lexicographically fisrt
string’s Rank (if there are multiple answers, choose the smallest
one), the string’s times in the N generated strings, lexicographically
last string’s Rank (if there are multiple answers, choose the smallest
one), and its times also.
Sample Input
abcderaaaaaaababab
Sample Output
1 1 6 11 6 1 61 3 2 3
思路
先说题意,题意是给一个字符串,然后让你把这个字符串左移,一共有这个字符串长度种表示方法,按照字典序顺序,找出最大的表示是第几次最小的表示是第几次,并且求出他们的出现次数。
输出的四个数字分别为:最小字典序的编号,最小字典序个数,最大字典序编号,最大字典序个数。
分析一下,就知道他们出现的个数其实就是求这个串的循环节的个数,要求编号,我们就通过最大最小表示法来求
关于字符串的最小表示法:
HDU 3374 String Problem (KMP+最大最小表示)
字符串的最小表示法
字符串匹配–最大最小表示法模板
【算法】字符串的最小表示法
代码
#include<cstdio>#include<cstring>#include<string>#include<set>#include<iostream>#include<stack>#include<queue>#include<vector>#include<algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define mod 10000007#define debug() puts("what the fuck!!!")#define ll longlongusing namespace std;const int N=1000000+20;int nxt[N];string s1,s2;void get_next(string s){ int len=s.length(); int j=0,k=-1; nxt[0]=-1; while(j<len) if(k==-1||s[j]==s[k]) nxt[++j]=++k; else k=nxt[k];}int get_min(string s){ int len=s.length()/2; int i=0,j=1; while(i<len&&j<len) { int k=0; while(s[i+k]==s[j+k]&&k<len) k++; if(k==len) break; if(s[i+k]<s[j+k]) { if(j+k>i) j+=k+1; else j=i+1; } else { if(i+k>j) i+=k+1; else i=j+1; } } return min(i,j);}int get_max(string s){ int len=s.length()/2; int i=0,j=1; while(i<len&&j<len) { int k=0; while(s[i+k]==s[j+k]) k++; if(k==len) break; if(s[i+k]>s[j+k]) { if(j+k>i) j+=k+1; else j=i+1; } else { if(i+k>j) i+=k+1; else i=j+1; } } return min(i,j);}int main(){ std::ios::sync_with_stdio(false); std::cin.tie(0); while(cin>>s1) { int len=s1.length(); get_next(s1); s2=s1+s1; int ans=len-nxt[len],cnt=1; if(len%ans==0) cnt=len/ans; cout<<get_min(s2)+1<<" "<<cnt<<" "<<get_max(s2)+1<<" "<<cnt<<endl; } return 0;}
优化版代码,可以直接用一个函数求出两个表示法:
#include<cstdio>#include<cstring>#include<string>#include<set>#include<iostream>#include<stack>#include<queue>#include<vector>#include<algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define mod 10000007#define debug() puts("what the fuck!!!")#define ll longlongusing namespace std;const int N=1000000+20;int nxt[N];string s;void get_next(string s){ int len=s.length(); int j=0,k=-1; nxt[0]=-1; while(j<len) if(k==-1||s[j]==s[k]) nxt[++j]=++k; else k=nxt[k];}int min_max_express(string s,bool flag)//参数为true时求最小表示法,为false为最大表示法{ int i=0,j=1,k=0; int len=s.length(); while(i<len&&j<len&&k<len) { int t=s[(j+k)%len]-s[(i+k)%len]; //二者相等,后移 if(t==0) k++; else { if(flag) { if(t>0) j+=k+1; else i+=k+1; } else { if(t>0) i+=k+1; else j+=k+1; } if(i==j) j++; k=0; } } return min(i,j);}int main(){ std::ios::sync_with_stdio(false); std::cin.tie(0); while(cin>>s) { int len=s.length(); get_next(s); int ans=len-nxt[len],cnt=1; if(len%ans==0) cnt=len/ans; cout<<min_max_express(s,true)+1<<" "<<cnt<<" "<<min_max_express(s,false)+1<<" "<<cnt<<endl; } return 0;}
- hdu3374 String Problem(最小最大表示法+KMP)
- HDU3374 String Problem(kmp,最大最小表示法)
- hdu3374 String Problem(KMP+最小表示法)
- HDU3374 String Problem(KMP + 最小表示法)
- HDU3374 String Problem(KMP + 最大最小表示)
- HDU3374(String Problem)字符串-最小表示法+KMP
- hdu3374-最小表示法&&kmp求循环节-String Problem
- hdu3374最大最小表示+kmp
- hdu3374 最小表示法+kmp
- hdu3374(最小表示法+KMP)
- hdu3374最小表示法+KMP
- hdu3374 最小最大表示法kmp求循环节
- hdu3374 String Problem (字符串最小表示)
- 【KMP】 hdu3374 String Problem
- HDU 3374 String Problem(最小最大表示法+KMP)
- String Problem + 最大(最小)表示法+KMP
- HDU 3374 String Problem KMP-最小最大表示法
- HDU 3374String Problem(最大最小表示法+KMP)
- 神一般的口诀 之 多态
- 43. 数据结构笔记之四十三最短路径之迪杰斯特拉(Dijkstra )算法
- AngularJS 自定义 server
- 古文觀止卷九_永州韋使君新堂記_柳宗元
- 计算机网络---网络规划与子网划分
- HDU3374 String Problem(kmp,最大最小表示法)
- RecyclerView的横向布局及点击事件(也可做瀑布流效果)
- 轮播与fragment联动
- 数据结构(二)饥饿与死锁的区别
- 44. 数据结构笔记之四十四弗洛伊德Floyd算法
- 字符串格式化-format()
- MVC模型 跟DAO模型的初步认识
- 大三的两场面试下来,我决定回学校读书
- filebeat浅析