• 递归练习题


    思考1.在不考虑n!溢出的情况下,编程实现阶乘问题

    C++实现

    比较简单,不多赘述,通过循环实现

    1. ll fac(int n){
    2.    ll res=1;
    3.    for(int i=1;i<=n;i++)res*=i;
    4.    return res;
    5. }

    子问题:求(n-1)! 子问题合并 :n*(n-1)!

    1. ll fac(int n){
    2.    if(n==0)return 1;
    3.    else return fac(n-1)*n;
    4. }

    python

    1. from math import *
    2. print(factorial(6))

    习题1

    题目:猴子吃桃,猴子每天吃一半多一个,第10天只剩1个,问第一天剩多少个

    从最后一天开始递归,要是d=1,表示第一天,直接输出rest; 不然逆推上一天,x=x-1,rest=(rest+1)*2

    C++实现

    1. #include
    2. using namespace std;
    3. int f(int d,int rest){
    4.    return ( d==1 ? rest : f(d-1,(rest+1)*2));
    5. }
    6. int main(){
    7.    cout<<f(10,1);
    8.    return 0;
    9. }

    python

    1. def f(d,rest):
    2.    if d==1 :
    3.        return rest
    4.    else :
    5.        return f(d-1,(rest+1)*2)
    6. print(f(10,1))

    习题二

    题目:三齿轮问题。三个齿轮,齿数分别为a,b,c,问各自转多少圈后,这两对齿重逢

    说实话没咋看懂题目,但根据题目样例应该是输出lcm(本身gcd就递归实现的)

    C++

    1. #include
    2. using namespace std;
    3. int gcd(int a,int b){
    4.    return !b ? a : gcd(b,a%b);
    5. }
    6. int main(){
    7.    int a,b,c;cin>>a>>b>>c;
    8.    cout<gcd(b,c)<<' ';
    9.    cout<gcd(a,c)<<' ';
    10.    cout<gcd(b,a)<<' ';
    11.    // C++自带gcd: __gcd()
    12.    return 0;
    13. }

    python

    python math中带有lcm,gcd

    1. from math import *
    2. a,b,c=3,4,5
    3. print(lcm(c,b),lcm(c,a),lcm(a,b))

    习题三

    题目:输入一个n(n\leqslant2000000000)求它的分解式总数(Eg.12 ---- 8)

    此题如果规模扩大,应该要用pollard rho,这里直接分解 可以得到递归公式f(x)=1+\sum_{t_i}^{t_i为

    C++

    下面用了 miller_rabin判断素数,因为有模板,直接贴了 或者存个质数的表,二分查找判素也行

    1. #include
    2. #define ll long long
    3. using namespace std;
    4. ll cnt=0,fac[10010];
    5. ll qpow(ll x,ll n,ll p) {
    6.    ll res=1;
    7.    while(n){
    8.        if(n&1)res=res*x%p;
    9.        x=x*x%p;
    10.        n>>=1;
    11.   }
    12.    return res;
    13. }
    14. bool query(ll p) {
    15.    int test[10]={2,3,5,7,11,13,17};
    16.    if(p==1)return 0;
    17.    ll t=p-1,k=0;
    18.    while(!(t&1))k++,t>>=1;
    19.    for(int i=0;i<4;i++){
    20.        if(p==test[i])return 1;
    21.        ll a=qpow(test[i],t,p),nxt=a;
    22.        for(int j=1;j<=k;j++){
    23.            nxt=(a*a)%p;
    24.            if(nxt==1 && a!=1 && a!=p-1) return 0;
    25.            a=nxt;
    26.       }
    27.        if(a!=1) return 0;
    28.   }
    29.    return 1;
    30. }
    31. ll f(ll x){
    32.    if(query(x) || x==1)return 1;
    33.    else {
    34.        ll res=0;
    35.        for(int i=0;i
    36.            if(x%fac[i]==0)res+=f(x/fac[i]);
    37.       }
    38.        res+=1;
    39.        return res;
    40.   }
    41. }
    42. int main(){
    43.    ll x;cin>>x;
    44.    for(int i=2;i*2<=x;i++){
    45.        if(x%i==0)fac[cnt++]=i;
    46.   }
    47.    cout<<f(x);
    48.    return 0;
    49. }

    python

    1. from Crypto.Util.number import *
    2. def f(x):
    3.    if isPrime(x) | x==1 :
    4.        return 1
    5.    else :
    6.        res=0;
    7.        for i in range(len(fac)):
    8.            if fac[i]>=x :
    9.                break
    10.            if x%fac[i]==0 :
    11.                res+=f(x//fac[i])
    12.        res+=1;
    13.        return res;
    14. fac=[]
    15. x=12
    16. for i in range(2,x//2+1) :
    17.    if x%i==0 :
    18.        fac.append(i)
    19. print(f(x))

    习题四

    题目:有重复元素的排列问题,输出有重复元素集合的排列

    next_permutation yyds bool next_permutation(iterator start,iterator end) next_permutation会把调整序列改为下一个字典序

    C++

    1. #include
    2. using namespace std;
    3. int main(){
    4.    string s("abcb");
    5.    sort(s.begin(),s.end());
    6.    do{
    7.        for(int i=0;isize();i++)cout<' ';
    8.        cout<
    9.   }while(next_permutation(s.begin(),s.end()));
    10.    return 0;
    11. }

    习题五

    题目:求一个集合的全部子集

    运用二进制数模拟子集的每个位置上的数是否取出

    C++

    1. #include
    2. using namespace std;
    3. int a[]={1,5,6,9};
    4. int main(){
    5.    for(int i=0;i<16;i++){
    6.    int tem=i;
    7.   for(int j=0;j<4;j++){
    8.            if(j&1)cout<' ';
    9.       }
    10.        cout<
    11.   }
    12.    return 0;
    13. }

    习题六

    题目:求n个数中r个数的全部组合问题

    1. #include
    2. using namespace std;
    3. int n,r;
    4. bool b[20];
    5. void print(){
    6. for(int i=1;i<=n;i++)
    7. if(b[i])cout<' ';
    8. cout<
    9. }
    10. void dfs(int k,int p){//k表示已经标记的个数 p表示搜索到的位置
    11. if(k==r) print();
    12. else if(p>n)return;//到最后位置后的一个位置
    13. else {
    14. b[p]=true;
    15. dfs(k+1,p+1);
    16. b[p]=false;
    17. dfs(k,p+1);
    18. }
    19. }
    20. int main(){
    21. cin>>n>>r;
    22. dfs(0,1);
    23. return 0;
    24. }

    习题八

    题目:某人上楼梯一次可以上1,2,3格,输出所有可能,总共n阶台阶

    简单递归,从最后一个台阶往前,a记录每次走了几阶,step表示走了几步,rest表示还剩下几阶要走

    C++

    1. #include
    2. using namespace std;
    3. int a[6];
    4. void f(int step,int rest){
    5.    if(rest==0){
    6.        for(int i=0;i
    7.            cout<' ';
    8.        cout<
    9.   }
    10.    else{
    11.        for(int i=1;i<=3 && i<=rest;i++){
    12.            a[step]=i;
    13.            f(step+1,rest-i);
    14.       }
    15.   }
    16. }
    17. int main(){
    18.    int n=5;
    19.    f(0,5);
    20.    return 0;
    21. }

    python

    类似C++

    1. a=[0]*6;
    2. def f(step,rest) :
    3.    if rest==0 :
    4.        for i in range(1,step+1):
    5.            print(a[i],end=' ')
    6.        print()
    7.    else :
    8.        for i in range(1,4):
    9.            if i>rest :
    10.                break
    11.            a[step+1]=i
    12.            f(step+1,rest-i)
    13. f(0,5)

    习题九

    题目:集合划分问题,将n个元素的集合划分为m个

    这道题跟6思路基本相同,先用6的方法得到m-1个划分的位置的所有可能,然后按照划分位置分别输出即可

    题解略


    习题十

    题目:n皇后问题(n*n棋盘),输出所有摆放方案

    $$
    \begin{matrix}

    0 & * & 0 \\

    * & 0 & 0 \\

    0 & 0 & *

    \end{matrix} \tag{1}
    $$

    写了好多次了 懒得写了

  • 相关阅读:
    PCIe寄存器之二
    我要给你讲的简单明了,Java就是值传递,不服来辩
    编码与进制
    遥感云计算的一个拐点
    python 中的迭代器和生成器简单介绍
    Redis+Nginx+ 设计模式 +Spring 全家桶 +Dubbo 阿里 P8 技术精选文档
    使用 redis 减少 秒杀库存 超卖思路
    C++11右值引用
    WebGIS 地铁交通线网数据可视化监控平台
    【Mybatis源码】XPathParser解析器
  • 原文地址:https://blog.csdn.net/m0_64839851/article/details/126752086