题目描述:
考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0.
例:
- 1010230 是有效的7位数
- 1000198 无效
- 0001235 不是7位数, 而是4位数.
给定两个数N和K, 要求计算包含N位数字的有效K-进制数的总数.
假设2 <= K <= 10; 2 <= N; 4 <= N+K <= 18.
题目解析:
题目最重要的一点就是相邻两个数之间不能同时为0,且第一个数不能为0。
解决这道题可以用递归的思想(分治),因为当确定了某一位的数字时,其有效数的总数目就可分为以下两种情况:
假设为十进制,f§:表示p条件下,有效数的总数目
- f(当前位为0) = f(下一位不为0)
- f(当前位不为0)= ( f(下一位为0) + f(下一位不为0) ) * (K - 1)
有了递归公式再想一下递归结束的条件,这道题也就基本上解决了。
递归结束条件:
- 当达到最后一位时,该位为0,则返回1;
- 当达到最后一位时,该位不为0,则返回K - 1。
//n表示此次函数调用要处理的是第几位(从左到右)的数字
//b表示第n位(也就是此次要处理的位)是否为0
int f(int n, bool b) {
if (n == N) {
if (b) return 1;
else return K - 1;
}
else {
if (b) return f(n + 1, false);
else return (f(n + 1, true) + f(n + 1, false)) * (K - 1);
}
}
总结:
其实我刚开始不是以这样的想法来做的(也没做出来),而且这个方法是我看了别人解析,不过我个人觉得他说得不是很好。
我刚开始看到这一道题一想到的就是组合排列,因为这个实在是太像高中学到的插空问题了,一直在想着如何计算出给定n个位置、x个0,这些0合格放法的组合数。可就是一直算不出来,一直在那钻,也没有心思去想其它办法(因为一直有一种我要解出来了的想法),不过我知道按我这个想法去做肯定是可以做出来的,而且执行速度会比这个快非常多,因为只需要计算公式就可以了。
这个时候才恨自己当时没有好好学~ 书到用时方恨少!