问题 G(1203): 【基础算法】01字符串问题

xiaoxiao2021-02-28  110

问题 G(1203): 【基础算法】0/1字符串问题 时间限制: 5 Sec 内存限制: 64 MB 提交: 127 解决: 25 [提交][状态][我的提交] 题目描述

输出仅由0和1组成的长度为N的字符串,并且其中不可含有三个连续的相同子串。

例如,110101就不含有三个连续的相同子串。而111010就含有一组长度为1的连续相同子串:111

输入

第1行:字符串长度n(n≤40) 输出

第1行:1个整数,表示满足条件的字符串的个数。 样例输入

(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

2

样例输出

4

提示

[提交][状态][讨论版]

理解的方向:

#include<iostream> #include<cstdio> #include<cstring> using namespace std; int num[100],t,n; int check(int k) { for(int i=1;i<=k/3;i++) //若长度为k,则分成 3份,每份的长度为总长k/3,这就是长度最长的子串。 { int flag=1; for(int L=1;L<=i;L++) //搜索增量L为1~i ,例如:check(3),check(4),check(5),分别会检查1,2,3和2 ,3,4和3,4,5 对于6呢,既要检查 //4,5,6,又要检查1 3 5,若135相同还要检查2,4,6,否则中止检查 if(num[k-3*i+L]!=num[k-3*i+L+i]||num[k-3*i+L]!=num[k-3*i+L+i+i]) //这个表达式是本题的难点,同学们记住第一个就行了,后面 //的两个数就好理解了,一个加i,另一个加i*2 { flag=0; //表明没有三个连续的子串 break; //无需判断内循环后面的情况,例如检查了147不合,无需检查258,跳出内循环,继续外循环 } if(flag) { return 0;} //有三个连续的子串,就终止,返回0。 } return 1; //没有三个连续的子串就返回1 } void dfs(int step) { if(step>n) { t++; return ; } for(int i=0;i<=1;i++) { num[step]=i; if(check(step)) //检查整个串,若得到到返回值1(即表明在当前长度为step的串中没有三个连续的子串, //就进入递归下一轮dfs,即:在当前字符串(num数组)再增加一个0/1字符,接着再去检查整个串,如此循环直到长度大于n,则计数 //器加1,如果返回值为0,就扔了刚增加的这个字符,换另一个字符) dfs(step+1); } } int main() { //freopen("d:\\out.txt","w",stdout); scanf("%d",&n); num[1]=0; dfs(2); //用户输入为1和2都是执行dfs(2) printf("%d\n",t*2); /*这个t值要乘以2,因为dfs(2)赋值是从2开始,dfs函数并未对num[1]赋值0和1(初始化时为0, 1的情况没有处理),所以答案要*2 或者你把上面的改成以下也可以。 num[1]=0; dfs(2); num[1]=1; dfs(2); */ return 0; }
转载请注明原文地址: https://www.6miu.com/read-78089.html

最新回复(0)