蓝桥杯字母组串问题分析
※看之前先把心静下来※
标题:字母组串
由 A,B,C 这3个字母就可以组成许多串。
比如:“A”,“AB”,“ABC”,“ABA”,“AACBB” …
现在,小明正在思考一个问题:
如果每个字母的个数有限定,能组成多少个已知长度的串呢?
他请好朋友来帮忙,很快得到了代码,
解决方案超级简单,然而最重要的部分却语焉不详。
请仔细分析源码,填写划线部分缺少的内容。
#include <stdio.h>
// a个A,b个B,c个C 字母,能组成多少个不同的长度为n的串。
int f(int a, int b, int c, int n)
{
if(a<0 || b<0 || c<0) return 0;
if(n==0) return 1;
return f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1); // 填空
}
int main()
{
printf("%d\n", f(1,1,1,2));
printf("%d\n", f(1,2,3,3));
return 0;
}
对于这道题先要看f函数的返回值及其结构,从结构看出,这个函数一定是一个递归结构,看到if(n==0) return 1;可以判断出下面的递归一定是把n-1作为参数传进去,才有可能使下面的递归达到n=0的条件,确定了最后的参数是n-1,前面的参数也就可以确定了,n代表字符串的长度,n-1说明从a,b,c三者中挑出来一个占了一位,所以前面肯定是f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1),下面来解释下这个递归的含义,拿题中给的第一组参数(1,1,1,2)为例:
两层层递归其实是代表了字符串长度为2的字符串每一个位置所用字母的情况,第一次递归确定了字符串第一个位置的字母,第二次递归确定了第二个位置的字母,其实也可以理解为:无限个a,b,c用来组成长度=2的字符串一共有几种情况,显然,结果为3*3=9种,但是题中a,b,c个数有限,所以其实是根据a,b,c的个数来除去不可行的方案,如上图,三叉树最左边的叶子节点,它代表第一个位置选a,第二个位置也选a,可是a只有一个,所以把这种方案舍去,其实就是深搜,判断每种情况的可行性。