POJ 1506 最小表示法
2015-09-20 15:33
253 查看
题意:给以一个最长10000的字符串,问你从哪一个字符开始它的字典序最小。
最小表示法:i,j表示当前以i,j所指向的字符为首元素的最优解,k表示*i和*j紧接着的字符有多少个是相同的且顺序也相同。
初始化:i=0,j=1,k=0;
其实如果要是比暴力优化一点就是,找出所有最小的字符,如果是一个那么这就是所求,如果是多个,就在这多个里面去找。理解i=i+k+1,j=j+k+1就行 了,然而我不知道怎么说,如果有通俗易懂的证法,留言给我啊!!!
最小表示法:i,j表示当前以i,j所指向的字符为首元素的最优解,k表示*i和*j紧接着的字符有多少个是相同的且顺序也相同。
初始化:i=0,j=1,k=0;
do if s[i+k]=s[j+k]; then k++; else if s[i+k]>s[j+k]; then i+k+1; else then j+k+1; if(i==j)//特判:两个指针指向同个字符 j++; while i<strlen&&j<strlen&&k<strlen
其实如果要是比暴力优化一点就是,找出所有最小的字符,如果是一个那么这就是所求,如果是多个,就在这多个里面去找。理解i=i+k+1,j=j+k+1就行 了,然而我不知道怎么说,如果有通俗易懂的证法,留言给我啊!!!
#include<iostream> #include<cstring> #include<cstdio> using namespace std; char a[10000+5]; int Min(int x,int y) { if(x<y) return x; return y; } void dispose(char *b,int len) { int i=0,j=1,k=0; while(i<len&&j<len&&k<len) { int t=b[(i+k)%len]-b[(j+k)%len]; if(!t) k++; else { if(t>0) i=i+k+1; else if(t<0) j=j+k+1; if(i==j) j++; k=0; } } printf("%d\n",Min(i,j)+1); } void Input() { memset(a,'\0',sizeof(a)); gets(a); dispose(a,strlen(a)); } int main() { int t; scanf("%d",&t); getchar(); while(t--) { Input(); } return 0; }
相关文章推荐
- 23设计模式之目录
- 客户端验证换了,服务器验证持性
- 深入Hibernate
- 用序列化器生成xml文件
- Linux中fork的使用(02)---fork的返回值
- 央视新闻报道XcodeGhost事件
- 央视新闻报道XcodeGhost事件
- 快速排序遇到的小问题
- Java之voliate, synchronized, AtomicInteger使用
- boost::filesystem指南
- CXF WebService整合Spring
- build linux kernel的错误
- java与javac命令的功用
- Linux Golang安装与环境变量设置
- VC中的stdafx.h简介(原理及作用)
- UVa1585——Score
- 【动态规划】leetcode - Maximal Square
- git基础
- 查找服务器变慢的方法
- 第3周项目4(1)——顺序表应用