困难的串的思考

问题描述:如果一个字符串包含两个相邻的重复子串,则称它为容易的串,其他串称为困难的串,如:BB,ABCDACABCAB,ABCDABCD都是容易的,D,DC,ABDAB,CBABCBA都是困难的。

输入正整数n,L,输出由前L个字符组成的,字典序第n小的困难的串。例如,当L=3时,前7个困难的串分别为:A,AB,ABA,ABAC,ABACA,ABACAB,ABACABA

思路很简单:

方法1,检查所有长度为偶数的子串,判断前一半和后一半是否相等,方法可以,但会做     很多重复的事情。

改进:与八皇后问题判断是否冲突的过程类似,判断当前皇后与前面的皇后是否冲突,无需再去判断前面的皇后是否冲突,因为在之前的过程中已经判断好了

所以,每次新加入一个字符的时候,只需判断加入这个字符后的串的后缀前面相等长度的串是否满足需求即可。

对于后缀的理解:加入这个字符后,串的长度为k,后缀分别为2,4,6...k/2,分别比较是否满足需求即可

#include<stdio.h>
#define MAX 90
int S[MAX];	//保存第i个位置应该放哪个字符
int n,L;
int dfs(int cur)	//返回0表示已经得到解
{		
	int i,j,k;
	if(cur == n)
	{
		for(i=0;i<cur;i++)
		{
			printf("%c",'A'+S[i]);
		}
		printf("\n");
		return 0;
	}
	for(i=0;i<L;i++)
	{
		int ok=1;	//判断方案是否合法
		S[cur]=i;	//将当前位置设定为i“0==A,1==B,2==C”
		
		for(j=1;2*j<=cur+1;j++)	//循环判断长度长度为j*2的后缀
		{
			int equal=1;	//判断后缀中是否有前一半是否等于后一半
			for(k=0;k<j;k++)
			{
				if(S[cur-k]!=S[cur-k-j]) //只要确定了后缀j*2中有一个不相等,则可以确定前一半与后一半不相等
				{
					equal=0;
					break;
				}
			}
			if(equal)
			{
				ok=0;
				break;
			}
		}
		if(ok)
		{
			if(!dfs(cur+1))	//到这里,说明0到cur位置的困难串已经确立好了,确立下一个位置就好
				return 0;
		}
	}
	return 1;
}
int main()
{
	while(scanf("%d%d",&n,&L)!=EOF)
	{
		memset(S,0,sizeof(S));
		dfs(0);
	}
	return 0;
}


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值