• 算法-递归


    例子1 全排列 n!

    #include <iostream>
    using namespace std;
    void swap(int& a,int& b){
        int r=a;
        a = b;
        b=r;
    }
    //将数组 第begin个数到第end个数之间的数进行全排列输出 
    void permutation(int* list,int begin, int end){
        if(begin==end){  //第end个数已经排好 可以输出了 
            for(int i=0;i<end;i++){
                cout<<list[i]<<",";
            }
            cout<<endl;
            return;
        }
        for(int i=begin;i<end;i++){
            swap(list[begin],list[i]);
            permutation(list,begin+1,end);
            swap(list[i],list[begin]);  //恢复数组原样 
        }
    }
    
    int main(){
        int n;
        int list[10]={1,2,3,4,5,6,7,8,9,0};
        cin>>n;
        permutation(list,0,n);
        for(int i=0;i<10;i++){
            cout<<list[i]<<" ";
        }
    }

    例子2:逆波兰表达式

    #include <iostream>
    using namespace std;
    
    //逆波兰表达式 
    double exp(){
        char r[10];
        scanf("%s",r);  //遇空格断开 
        switch(r[0]){
            case '+': return exp() + exp();
            case '-': return exp() - exp();
            case '*': return exp() * exp();
            case '/': return exp() / exp();
            default: return atof(r);
        }
    }
    
    
    int main(){
    double ans;
    ans = exp();
    cout<<ans;
    }
    #include <iostream>
    using namespace std;
    
    //逆波兰表达式 转化为普通表达式 
    void exp(){
        char r[10];
        scanf("%s",r);  //遇空格断开 
        switch(r[0]){
            case '+': cout<<"(";exp();cout<<"+";exp();cout<<")"; break;
            case '-': cout<<"(";exp();cout<<"-";exp();cout<<")"; break;
            case '*': cout<<"(";exp();cout<<"*";exp();cout<<")";break;
            case '/': cout<<"(";exp();cout<<"/";exp();cout<<")";break;
            default: cout<<r;
        }
    }
    
    
    int main(){
    exp();
    }

    例子3 普通表达式的计算

    #include <iostream>
    using namespace std;
    //表达式的常规计算
    //基本思想 : 表达式由项组成(以+或-连接起来的不同部分) 
    //项由因子组成(以*或/连接起来的不同部分)
    //因子又是由数字或表达式组成的,表达式由括号扩着 
    //数字和数字之间可以直接计算
    
    double expValue();
    double factorValue(){
        //读入并计算一个因子的值
        double v;
        char c = cin.peek();
        if(c=='('){  //在括号里面说明是表达式 
            cin.get();
            v = expValue(); 
            cin.get();
        }
        else{
            cin>>v;
        }
        return v;
    }
    
    double itemValue(){
        //读入并计算项的值
        double v=factorValue();
        while(1){  
            char c=cin.peek();
            if(c=='/'){
                cin.get();
                v /= factorValue();
            }
            else if(c=='*'){
                cin.get();
                v *= factorValue();
            }
            else{
                break;
            }
        } 
        return v;
    }
    
    double expValue(){
        //计算表达式的值
        double v=itemValue();
        while(1){  //重复提取计算符号和表达式 
            char c= cin.peek();
            if(c=='+'){
                cin.get();
                v += itemValue();
            }
            else if(c=='-'){
                cin.get();
                v -= itemValue();
            }
            else{
                break;
            }
        } 
        return v;
    } 
    
    int main(){
        cout<<expValue()<<endl;
    }

    例子4:分割棋盘

    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <iomanip>
    using namespace std;

    //棋盘分割  每个棋格都代表一个数
    //用一刀切法 切割指定次数 分割给定的正方形棋盘 ,分成的矩形小棋盘的值是其所有格子之和
    //求使得各矩形小棋盘总分的均方差最小值
    //分析问题 大棋盘是给定的,n也是给定的 所以无论怎么分 分成的矩形小棋盘总分的均值总是相同的
    //各矩形小棋盘只由 各个小棋盘的总分平方和决定
    //因此问题转化为 求将一个给定的棋盘分成指定个矩形,矩形的总分的平方和最小为多少。

    //给每个格子(x,y)坐标
    int sum[9][9];//sum(i,j)是棋盘(1,1)到(i,j)的总分
    int result[16][9][9][9][9];//result(n,x1,y1,x2,y2)是将(x1,y1)和(x2,y2)构成的矩形分成n块,的最小值
    int smallsum(int x1,int y1,int x2,int y2){  //(x1,y1)到(x2,y2)的总分
        return sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];
    }

    int fun(int n,int x1,int y1,int x2,int y2){
        //以(x1,y1)为左定点,(x2,y2)为右定点的矩形,分成n个矩形后 最小的平方和
        //中止条件 横向最多切 x2-x1 , 纵向最多y2-y1, 必须切n-1,所以x2-x1+y2-y1>=n-1
        int v = 1<<30;
            if(n==1){
            int t=smallsum(x1,y1,x2,y2);
            return t*t;
            }

        if(x2-x1+y2-y1<n-1){
            return v;
        }
            if(result[n][x1][y1][x2][y2]!=-1){
             return result[n][x1][y1][x2][y2];
      }
             

        //对 x1-x2之间所有能切的的切法进行遍历
        for(int x=x1;x<x2;x++){
            int left=smallsum(x1,y1,x,y2);
            int right=smallsum(x+1,y1,x2,y2);
            int t=min(fun(n-1,x+1,y1,x2,y2)+left*left,fun(n-1,x1,y1,x,y2)+right*right);
            v = min(v,t);
        }
        //对y1-y2之间所有能切的切法进行遍历
        for(int y=y1;y<y2;y++){
            int up=smallsum(x1,y1,x2,y);
            int down=smallsum(x1,y+1,x2,y2);
            int t=min(fun(n-1,x1,y1,x2,y)+down*down,fun(n-1,x1,y+1,x2,y2));
            v = min(v,t);
        }
        result[n][x1][y1][x2][y2] = v;
        return v;
    }
     
    int main(){
        int n;
        memset(sum,0,sizeof(sum));//置0
        memset(result,0xff,sizeof(result));//置-1
        cin>>n;
        for(int i=1;i<=8;i++){
            int rowsum = 0;
                for(int j=1;j<=8;j++){
                    int s;
                    cin>>s;
                    rowsum +=s;
                    sum[i][j]=sum[i-1][j]+rowsum; //上一行以上的矩形+ 本行的矩形
                }
           
        }
        //输出均方差
         int squareSum = fun(n,1,1,8,8);
         double result = n*squareSum - sum[8][8]*sum[8][8];
         cout<<setiosflags(ios::fixed) << setprecision(3) <<sqrt(result/(n*n));
    }

    例5.放苹果问题

    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <iomanip>
    using namespace std;
    
    //放苹果问题  将m个苹果放到n个盘子里,允许有的盘子空着不放 
    int appway(int m,int n){
        if(m==0){
            return 1;
        }
        if(n==0){
            return 0;
        }
        if(n>m){
            return appway(m,m);
        }
        //下面处理盘子数目小于等于苹果数的情况
        return  appway(m,n-1)+appway(m-n,n);
    }
    int main(){
        int m,n;
        cin>>m>>n;
        cout<<appway(m,n);
    }
  • 相关阅读:
    九九乘法表
    计算器界面
    3.2封装的日期类
    杨辉三角
    100以内的素数
    九九 乘法表
    七、logging模块
    六、MySQLdb 模块
    四、浏览器运行模式
    五、configparser模块
  • 原文地址:https://www.cnblogs.com/Latticeeee/p/9068330.html
Copyright © 2020-2023  润新知