倍减序列:一个以正整数k开始的倍减序列,是一个不定长的有序的正整数序列,它的第一个元素为k,第二个元素不大于第一个元素的一半,第三个元素不大于第二个元素的一半,依此类推。
例如,下面列出了所有的以6开始的倍减序列,共有6个:
6
6 1
6 2
6 2 1
6 3
6 3 1
任务要求:对于给定的正整数k,请找出以k开始的倍减序列的个数。
这几天训练的时候碰到了这个题,百思不得其解的时候就连CSDN上都没有详细的解题分享(有但是那位老哥是用java写的,初学者只会C看不懂)!!!
于是在和同学的交流和自己的琢磨下我终于摸清了逻辑,相信大多数和我一样数学思维还不太好的同学都会有种“脑子:我会了,手:不,你不会”的初看好像很简单,但是要实现却无从下手的感觉,因为这个题目用到了堪称编程中最难的知识点之一:递归。
为了不让更多同学深陷苦海,我决定写下这篇博客
#include <stdio.h>
int Demultiplication(int k){
int count = 0;//最外层,也就是根的计数器count,之后递归中的count都是每个分支的
if(k == 1) return 1;//为1时就可以结束当前分支的位数是否能继续进位的判断了
else count++;
k /= 2;
for(int i = 1;i <= k;i++){//实现遍历每位数上从1开始<=当前位数最大值k的数
count += Demultiplication(i);
}
return count;
}
int main(){
int k;
scanf("%d",&k);
printf("%d",Demultiplication(k));
return 0;
}
实际上这个题目确实不难,但是对于算法初学者来说想要理清它的思路也不简单,在这里我详细地讨论下自己的思路:
首先我们要有树的概念,最初输入的数就是根,而不同分支就是枝,同时枝也是更细的枝的根,也就是二叉树的思想,通过观察不难发现其实所有序列的最终最高位都是1,所以我们可以把k是否为1作为判断当前分支是否能继续进位的条件,当所有进位结束后,我们就可以将每个分支上的count回溯给根了,最后输出最初的根的count数即可。
尾言:这是小白写的第一篇博客,有所纰漏还请指正,也可以相互学习,祝大家都能在追梦路上勇往直前,咱有缘再见~