hdu3374 最小最大表示法kmp求循环节
2015-09-16 10:32
393 查看
题意:一个字符串的同构串中字典序最小的跟字典序最大,都要求输出起始下标最小的,然后这两个同构串在所有同构串中出现的次数。
求字典序最小最大直接最小最大表示法。出现次数的话,如果该字符串能多次出现一个同构串,那么这个字符串的循环节要大于1,不然就只能出现一次,所以用kmp求一下循环节就行了
求字典序最小最大直接最小最大表示法。出现次数的话,如果该字符串能多次出现一个同构串,那么这个字符串的循环节要大于1,不然就只能出现一次,所以用kmp求一下循环节就行了
#include <iostream> #include <string.h> #include <cstdio> using namespace std; const int N=1000010; int len,nextt ; char str ; int work(int m) { int i,j,l; i=0; j=1; while(i<m && j<m) { for(l=0;l<m;l++) if(str[(i+l)%m]!=str[(j+l)%m]) break; if(l>m) break; if(str[(i+l)%m] > str[(j+l)%m]) i=i+l+1; else j=j+l+1; if(i==j) j=i+1; } if(i<j) return i; return j; } int work2(int len,char pat[]) //最大表示法 { int i=0,j=1,k=0; while(i<len && j<len && k<len) { int t = pat[(i+k)%len] - pat[(j+k)%len]; if(!t) k++; else { if(t>0) j = j+k+1; else i = i+k+1; if(i == j) j++; k = 0 ; } } return i<j?i:j; } int get_next() { nextt[0]=0; for(int i=1;i<len;++i){ int temp=nextt[i-1]; while(temp&&str[temp]!=str[i]) temp=nextt[temp-1]; if(str[i]==str[temp]) nextt[i]=temp+1; else nextt[i]=0; } int x=len-nextt[len-1]; if(len%x==0) { int y=len/x; return y; } else return 1; } int main(){ while(~scanf("%s",str)){ len=strlen(str); int x=get_next(); int y=work(len); int z=work2(len,str); printf("%d %d %d %d\n",y+1,x,z+1,x); } return 0; }
相关文章推荐
- Webview ZoomButtonsController
- 连续最长子序列
- 关于JSP中的九大内置对象和四大作用域。
- zepto的tap事件的点透问题的几种解决方案
- iOS 9应用开发基础教程下册
- CSS伪类的概念及作用
- FRONT服务器内存溢出
- oracle笔记
- 一个少年电脑病毒作者的独白
- css 页面布局,自适应高度,居中,背景半透明
- 一次移动记账App的设计探索
- C#中浅拷贝与深拷贝(复制)
- plsql数据库密码过期的解决方法
- 友盟集成新浪登录分享5668
- J - Sabotage - UVA 10480(最大流)
- 关于jQuery双事件多重加载的问题。
- c#读取图片文件信息并转换成16进制文本方法
- C# 委托、事件、回调
- LeetCode 2 链表操作(带进位的加法运算)
- IE8的css hack \9 使用说明