HDU - 3374 String Problem (最大最小值表示法+kmp)

https://vjudge.net/contest/189927#problem/M


题意:字符串的第一个会变到最后一个,之后有一个顺序,第一次变化是第一名,第二次变化是第二名,然后问你字典序最小和字典序最大的串在第几名,它出现的次数是多少

思路:出现的次数好算,因为一个串出现的次数就是len/(len-nex[len])吗,现在就是看他是第几位比较难,其实也不难就是看一个字符在字符串中的大

#include <stdio.h>
#include <iostream>
#include <string.h> 
using namespace std;
const int maxn = 1e6+10;
char ch[maxn];
int nex[maxn],cnt[26];
void pre_kmp(char str[])
{
	memset(nex,0,sizeof(nex));
	int len = strlen(str) , i = 0 , k = -1;
	nex[0] = -1;
	while( i < len )
	{
		if( k == -1 || str[i] == str[k])
		{
			i++,k++;
			nex[i] = k;
		}
		else 
		{
			k = nex[k];
		}
	}
}
int Min_MAX(char str[],int flag)
{
	int i = 0 , j = 1 , k = 0;
	int len = strlen(str);
	while( i<len && j<len && k<len )
	{
//		puts("-----\n");
		int t = str[(j + k)%len] - str[(i+k)%len];
		if(t == 0)
		{
			k++;
		}
		else 
		{
			if(flag)
			{
				if(t<0)
				{
					i+= k+1;
				}
				else 
				{
					j+= k+1;
				}
			}
			else
			{
				if(t<0)
				{
					j+= k+1; 
				}
				else 
				{
					i+= k +1;
				}
			}
			if(i == j) j++;
			k = 0;
		}
	}
	return min(i,j);
}
int main()
{
	while(scanf("%s",ch)!=EOF)
	{
		memset( cnt , 0 , sizeof(cnt) );
		pre_kmp(ch);
		int len = strlen(ch);
		int ans;
		if( len % (len - nex[len]) ==0 ) ans = len / (len - nex[len]);
		else ans = 1;
		int s = Min_MAX(ch,1);
		int e = Min_MAX(ch,0);
		printf("%d %d %d %d\n",s+1,ans,e+1,ans);
	}
}

小位置就好了,这里就用到最大最小表示法,(表示自己并不是很会用= =。。过几天在在写一篇吧)上代码:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值