困难的串的思考
程序员文章站
2024-03-16 22:39:22
...
问题描述:如果一个字符串包含两个相邻的重复子串,则称它为容易的串,其他串称为困难的串,如: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;
}
上一篇: threejs学习(八)-- raycaster拾取物体
下一篇: 约瑟夫环问题
推荐阅读
-
困难的串的思考
-
ACM题目————困难的串
-
在字符串中找出第一个只出现一次的字符。
-
的含义
博客分类: JavaHibernate java字符串日期hibernatehbm2ddl ">
Java 字符串转换为日期,hibernate配置文件
的含义 博客分类: JavaHibernate java字符串日期hibernatehbm2ddl -
塔的思考与子弹发射
-
<二> Google Gson 转换Json字符串和对象(日期,枚举的转化) 博客分类: JSON Gson枚举日期内嵌对象
-
Java 编程下字符串的 16 位、32位 MD5 加密
-
jackson把null替换为" "的2种方式 博客分类: JDK//Demo通信//WS jsckson替换null为""jacksonjson串儿
-
每天一道LeetCode-----给定字符串s和字符数组words,在s中找到words出现的位置,words内部字符串顺序无要求
-
在一个字符串中找到第一个只出现一次的字符