【模板】字符串算法-字符串最小表示法
来源:互联网 发布:淘宝双十一促销方案 编辑:程序博客网 时间:2024/06/05 07:56
2014年10月,刚进hdu参加新生赛的时候,就遇到了字符串最小表示法的裸题,然而那时什么都不会的我只得写暴力,自然TLE了。之后在湖南师范大学第六届大学生计算机程序设计竞赛2B上,又做到了同样的裸题。
/*字符串算法-字符串最小表示法模板这是一个可以用O(n)时间解决"字符串呈环状,每一位置都可以作为首位,找出以哪个位置为开头,可以使得这个字符串的字典序最小(或最大)"问题的算法。*/#include<stdio.h>#include<string.h>const int M=5e6+10;int casenum,casei;int p;char a[M];int getmin(char s[]){ int i=0,j=1,k=0;//i和j是两个进行比较的起始匹配位点,k是匹配长度 int len=strlen(s); while(i<len&&j<len&&k<len) { int t=s[(i+k)%len]-s[(j+k)%len];//比较两个串的大小关系 if(t==0)k++;//如果相同,匹配长度增大,比较位置向移 else //如果不同,则字典序大的位置肯定不会是答案,改变那个匹配位点 { if(t>0)i+=k+1; else j+=k+1; if(i==j)j++;//i和j一定要错开 k=0;//匹配长度要重置为0 } } return i<j?i:j;//因为字典序大的位置被后移了,所以较小的位置就是答案}int main(){ scanf("%d",&casenum); while(casenum--) { scanf("%s",a); p=getmin(a); printf("%d\n",p); }}/*【题意】字符串呈环状,每一位置都可以作为首位,以哪个位置为开头,可以使得这个字符串的字典序最小(或最大)?【类型】字符串算法-字符串最小表示法【分析】这个算法其实自己想也能想出来。因为就算是自己设计的话,也应当是——把这个字符串的0号位点与1号位点相比较,如果一样,继续向后延伸比较,如果不一样,肯定大的那个显然不会是答案,改变匹配串。这里其实唯一需要理解的地方就是——if(t>0)i+=k+1;else j+=k+1;为什么这里是变成k+1,中间的内容可以完全跳过呢?(比如t>0)因为我们已经有{s[i]~s[i+k-1]==s[j]~s[j+k-1]了,且有s[i+k]>s[j+k],自然我们选i~i+k中的任意一点都是比j~j+k的相应位置要差的,所以自然可以都略过}【时间复杂度&&优化】i,j,k在某个位点都最多从0走到len,所以时间复杂度为O(n)【trick】【数据】Sample Input4bcda aaaaadabSample Output3002*/
ps:这套题虽然质量不高,还有两道错题2333,但是有三道裸题(2B字符串最小表示法、3C网络流和6F矩阵快速幂),对这些算法生疏的ACMer,可以拿来练手哦~~
0 0
- 【模板】字符串算法-字符串最小表示法
- 【模板】字符串算法-字符串最小表示法
- 字符串最小表示模板
- 字符串 最小表示法 O(n)算法 【模板】
- 字符串 最小表示算法
- 字符串的最大最小表示法 模板
- 个人模板 字符串最小表示法
- 字符串最小表示法 O(n)算法
- 字符串最小表示法 O(n)算法
- 字符串 最小表示法 O(n)算法
- 字符串最小表示法 O(n)算法
- 字符串同构最小最大表示法模板&&manacher模板
- 字符串最小表示法
- 字符串最小表示法
- zoj 2006 1729 字符串最小表示法 模板
- zoj 2006 1729 字符串最小表示法 模板
- 理解字符串循环同构的最小/最大表示法+模板
- 字符串处理 --- 最小表示法
- <select>里动态添加option
- test
- 第13周项目3 Dijkstra算法的验证
- (第十二周项目1)图基本算法库
- 第十一周项目3 中序线索化二叉树算法
- 【模板】字符串算法-字符串最小表示法
- 十四周 项目三-是否二叉排序树
- 第十周 项目3-利用二叉树遍历思想解决问题
- 第十四周项目1-(1)验证折半查找算法
- (第十二周项目2)操作用邻接表存储的图
- 第八周:串的链式存储
- 第十三周项目3-Dijkstra算法的验证
- 第十四周 项目1-验证算法(4)
- OC-5.NSArray