POJ 1506 最小表示法

题意:给以一个最长10000的字符串,问你从哪一个字符开始它的字典序最小。

最小表示法: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;
}





你可能感兴趣的:(最小表示法)