数据结构实验(二)递归函数练习

6-1 递归法求Fibonacci数列第n项的值

这道题就是写一个简单的递归函数即可

int fun( int n ){
    if( n == 1 || n == 2 ) return 1;
    return fun(n-1) + fun(n-2);
}

6-2 分治法求解金块问题

这道题就是典型的分治

[l,r],区间的中点是mid,那么a[l,r]的最小值就是min( a[l,mid]的最小值 , a[mid+1,r]的最小值 )

一直递归就好,边界就是l+1==r此时返回min( a[l] , a[r] )就好,或者是l==r返回a[l]即可。

最大值同理

int Max( int x , int y ){
    if( x >= y ) return x;
    return y;
}

int Min( int x , int y ){
    if( x <= y ) return x;
    return y;
}

int max( int a[ ] , int l , int r ){
    if( l == r ) return a[l];
    else if( l + 1 == r ) return Max( a[l] , a[r] );

    int mid = ( l + r ) >> 1;
    return Max( max( a , l , mid ) , max( a , mid + 1 , r ) );
}

int min( int a[ ] , int l , int r ){
    if( l == r ) return a[l];
    else if( l + 1 == r ) return Min( a[l] , a[r] );

    int mid = ( l + r ) >> 1;
    return Min( min( a , l , mid ) , min( a , mid + 1 , r ) );
}

6-3 正整数的分解方式

这道题就是枚举一下\(i\in[k,n]\),找到所有可以整除的\(i\),然后把decompose( n / i , i )累加起来就好,边界条件就是n==1。除此之外一定会走到一些不合法的情况,这种情况的边界就是n<k此时能整除n的数一定比上一个要小。

int decompose(int n,int k){
    if( n == 1 ) return 1;
    if( n < k ) return 0;
    int cnt = 0;
    for( int i = k ; i <= n ; i ++ )
        if( n % i == 0 ) cnt += decompose( n / i , i ) ;
    return  cnt;
}

7-1 快速幂

这道题就是快速幂的模板了吧,属于很常用的算法了。

#include<iostream>

int main(){
    auto pow = []( long long x , long long y ){// lambda 函数
        long long res = 1;
        while( y ){
            if( y & 1 ) res = res * x ;
            y >>= 1;
            x = x * x;
        }
        return res;
    };
    long long a , b;
    while( std::cin >> a >> b )
        std::cout << pow( a , b ) << "\n";
    return 0;
}

7-2 孔融分梨(函数实现)

这题实际上就是把分数通分一下就可以的

#include<bits/stdc++.h>
using namespace std;

int main(){
    int a , b , d ;
    scanf("%d,%d\n" , &a , &b );
    if( a < 1 || a > 10000 || b < 1 || b > 10000 ) 
        cout << "Input error!" , exit(0);
    d = __gcd( a , b );
    printf("%d/%d" , a / d , b / d );
    return 0;
}

7-3 汉诺塔问题

十分经典的汉诺塔问题,而且不是扩展版本的。

假如把n个盘子,从x移动到y(这里的x,y是任意的两个柱子,)就一定先把前n-1个盘子从x移动到z(这里的z是除了x,y的第三根柱子),然后把nx移动到y,最后把前n-1个盘子从z移动到y

然后就会发现这其实是一个递归下去的过程,一直递归到只剩下盘子1x移动到y这是直接移动就好了。

理清思路代码还是很简短的。

#include<bits/stdc++.h>
using namespace std;

char op( int x , int y ){
    if( x > y ) swap( x , y );
    if( x == 'a' ){
        if( y == 'b' ) return 'c';
        return 'b';
    }
    if( x == 'b' ) return 'a';
}

void f( int t , char x , char y ){
    if( t != 1 ) f( t-1 , x , op( x , y ) );
    cout << "No." << t << " disk: " << x << "->" << y << "\n";
    if( t != 1 ) f( t-1 , op(x,y) , y );
}

int main(){
    int n;
    cin >> n;
    f( n , 'a' , 'c' );
    return 0;
}
posted @ 2022-09-08 00:19  PHarr  阅读(162)  评论(0编辑  收藏  举报