hdu3374 String Problem

本文介绍了如何使用最小表示法和最大表示法来找到字符串循环移位后的字典序最小和最大下标,并计算出现次数。通过KMP算法计算最小循环周期,实现高效求解。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374


题解:循环移位,找字典序最前的和字典序最后的下标标号,然后把次数也输出来。

用最小表示法和最大表示法找到字典序最小和最大的字符串。用kmp计算出现的次数(最小循环周期)。

//http://blog.youkuaiyun.com/coraline_m/article/details/9834619


#include <stdio.h>
#include <string.h>
#define MAXN 1000002

char str1[MAXN];
int next[MAXN],len;

void getNext()
{
	int i=0,j=-1;
	next[0]=-1;
	while(str1[i]!='\0')
	{
		if(j==-1||str1[i]==str1[j])
		{
			i++;
			j++;
			next[i]=j;
		}
		else
			j=next[j];
	}
}

int getMin()//最小表示法
{
	int i=0,k=0,j=1,t;
	while(i<len&&j<len&&k<len)
	{
		t=str1[(i+k)%len]-str1[(j+k)%len];
		if(!t)
			k++;
		else
		{
			if(t>0)
				i+=(k+1);
			else
				j+=(k+1);
			if(i==j)
				j++;
			k=0;
		}
	}
	return i<j?i:j;
}

int getMax()//最大表示法
{
	int i=0,k=0,j=1,t;
	while(i<len&&j<len&&k<len)
	{
		t=str1[(i+k)%len]-str1[(j+k)%len];
		if(!t)
			k++;
		else
		{
			if(t>0)
				j+=(k+1);
			else
				i+=(k+1);
			if(i==j)
				j++;
			k=0;
		}
	}
	return i<j?i:j;
}

int main()
{
	int cnt,temp;
	while(scanf("%s",str1)!=EOF)
	{
		len=strlen(str1);
		getNext();
		temp=len-next[len];
		cnt=1;
		if(len%temp==0)
			cnt=len/temp;
		printf("%d %d %d %d\n",getMin()+1,cnt,getMax()+1,cnt);
	}
	return 0;
}



### HDU 2894 Problem Solution The task involves creating the shortest possible string that retains all characters from two provided strings while maintaining their original sequence. This problem can be approached using dynamic programming (DP). The core idea is to find common subsequences between both strings efficiently. #### Dynamic Programming Approach To solve this issue effectively, one method employs DP tables where each entry `dp[i][j]` represents the minimum length needed when considering substrings up until positions i and j respectively within the first and second word[^3]. For instance: Given sample inputs like those described in the reference material[^2], an effective strategy would involve constructing a table iteratively based on whether matching letters exist at current indices across compared words. If they do match, no additional character needs adding; otherwise, take into account extending either substring by including its next unmatched letter. ```python def compute_shortest_name(fruit1, fruit2): m, n = len(fruit1), len(fruit2) # Initialize DP matrix with dimensions (m+1)x(n+1) dp = [[0] * (n + 1) for _ in range(m + 1)] # Fill base cases along edges representing empty prefixes/suffixes for i in range(1, m + 1): dp[i][0] = i for j in range(1, n + 1): dp[0][j] = j # Populate remaining cells according to recurrence relation for i in range(1, m + 1): for j in range(1, n + 1): if fruit1[i - 1] == fruit2[j - 1]: dp[i][j] = dp[i - 1][j - 1] + 1 else: dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1 result_length = dp[m][n] # Reconstruct resulting merged string backwards starting from bottom-right corner index_i, index_j = m, n output_string = [''] * result_length while index_i > 0 or index_j > 0: if index_i > 0 and index_j > 0 and fruit1[index_i - 1] == fruit2[index_j - 1]: output_string[result_length - 1] = fruit1[index_i - 1] index_i -= 1 index_j -= 1 elif index_i > 0 and (index_j == 0 or dp[index_i - 1][index_j] < dp[index_i][index_j - 1]): output_string[result_length - 1] = fruit1[index_i - 1] index_i -= 1 else: output_string[result_length - 1] = fruit2[index_j - 1] index_j -= 1 result_length -= 1 return ''.join(output_string) # Example usage demonstrating how function works with test data points as per specification. print(compute_shortest_name('abc', 'bcd')) # Expected Output: abcd ``` This code snippet demonstrates building upon previously computed values through iteration over pairs of indexes corresponding to respective lengths traversed so far inside source terms being concatenated together optimally without redundancy whenever feasible under constraints outlined earlier regarding valid transformations allowed during processing steps involved hereafter.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值