递归的一些经典应用

今天看了一些关于递归的知识,顺便学习了一些经典的问题,敲了一些小代码

首先是递归实现的经典的二分问题,代码如下

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

int a[10] = {1,2,3,4,5,6,7,8,9,10};

int BinSearch(int left, int right, int goal){

    if(left>right) return -1;
    int mid = (left+ right)/ 2;
    if(a[mid]== goal) return mid+1 ;
    else if(a[mid]> goal) BinSearch(left,mid,goal);
    else if(a[mid]< goal) BinSearch(mid+1,right,goal);
}

int main(){
        int num = 3;
        while(num--){
            int x;
            cin>>x;
            cout<<"元素位于"<<BinSearch(0,9,x)<<endl;
        }
}


汉诺塔问题

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

int sum;
void hanio(int n, char X, char Y, char Z){
    if(n==1) {sum++;cout<<n<<" 从 "<<X<<" 移动到 "<<Z<<endl;}
    else{

        hanio(n-1, X, Z, Y);   //将前n-1个从x借助z移动到y
        cout<<n<<" 从 "<<X<<" 移动到 "<<Z<<endl; //将第n个从x移动到z
        sum++;
        hanio(n-1,Y, X, Z); //将n-1个从y借助x移动到z
    }
}

int main(){

    int x;

    cout<<"请输入要个数,输入0表示结束"<<endl<<endl;
    cin>>x;
    while(x){
        hanio(x,'X','Y','Z');
        cout<<sum<<endl;
        sum=0;
        cout<<"请输入要个数,输入0表示结束"<<endl<<endl;
        cin>>x;
    }
    return 0;
}

接下来是经典的N皇后问题

  这是自己写的代码

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

int cnt = 0;
int x;

int safe(int row, int col,int xx[][10]){

    int i,j,k;
    int flag = 0;
  //这里是进行判断当前位置是否可以放置,我一开始用一个标志量并且break ,结果总是会出现重复 !_ !,有知道的
    for(i=0;i<x;i++){   //  并且刚好看到的还希望告知 ^_^
       if(xx[i][col])
           return 0;
    }

    for(i=row, j=col ;i>=0 && j>=0 ;i--, j--){
        if(xx[i][j]){
           return 0;
        }
    }

    for(i=row, j=col; i<x &&j<x; i++, j++ ){
        if(xx[i][j]){
           return 0;
        }
    }

    for(i=row , j=col; i<x && j>=0; i++, j--){
        if(xx[i][j]){
            return 0;
        }
    }

    for(i=row, j = col ;i>=0 && j<x; j++, i--){
        if(xx[i][j]){
            return 0;
        }
    }

    return 1;
}

void display(int xx[][10]){   //输出每一种走法的棋盘
    int i,j;
    cout<<"第"<<cnt<<"种走法"<<endl;
    for(i=0; i<x; i++){
        for(j=0; j<x; j++){
            cout<<xx[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
}

void Queen(int row, int xx[][10]){

    int i,j,k;
    int tmp[10][10];

    for(i=0;i<x;i++)
        for(j=0;j<x;j++)
            tmp[i][j]=xx[i][j];

    if(row == x){
        cnt++;
        display(tmp);
    }
    else{
        for(i=0;i<x;i++){
            if(safe(row,i,tmp) ){

                for(k=0;k<x;k++) tmp[row][k] = 0; // 清空当前可走的这一列

                tmp[row][i] = 1;
                Queen(row+1,tmp);
            }
        }
    }
}

int main(){

    int chess[10][10];
    cout<<"输入皇后层数,0表示结束"<<endl;
    while(cin>>x && x){
            cnt = 0;
        for(int i=0;i<x;i++)
                    for(int j=0;j<x;j++) chess[i][j] = 0;
        Queen(0,chess);
        cout<<"总共有"<<cnt<<"种走法"<<endl;
    }
    return 0;
}

下面是参考别人的代码,瞬间泪崩 * _ *,写得真是精简,而且思路特别好,涨姿势了。

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

int cnt = 0;
int x;
int queen[10];

int isvalid(int i){
    for(int j=0;j<i;j++){
        if(queen[i]==queen[j]) return 0;

        if(abs(queen[i]-queen[j])==(i-j)) return 0 ;
    }
    return 1;
}
void display(){

    cout<<"第"<<cnt<<"种下法"<<endl;
    for(int i=0;i<x;i++){
        for(int j=0;j<x;j++){
            if(i==queen[j])
                cout<<"Q"<<" ";
            else cout<<"#"<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
}
void Queen(int i){

    if(i==x){
            cnt++;
            display();
        }
    else{
        for(int j=0;j<x;j++){
            queen[i]=j;
            if(isvalid(i))
                Queen(i+1);
            }
    }
}
int main(){

    while(cin>>x && x){
            cnt =0;
        Queen(0);
        cout<<cnt<<endl;
    }
    return 0;
}

  未完待续。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值