练习题1——递归算法设计

练习题1——递归算法设计

 

练习题:

  1. 输入一个自然数(<90000),  分别用递归法和非递归法求其二机制表示.

递归:

源码:

#include <iostream>

using namespace std;

int dec2bin(int n);

int main()

{    int n;

      cout<<"请输入一个整数:";

      cin>>n;

      cout<<n<<"对应的二进制形式为:";

      cout<<dec2bin(n);

      cout<<endl;

      return 0;

}

int dec2bin(int n)

{

    int sum;

    if(n==1)

    return 1;

    else

    {

        if(n==0)

        {

            return 0;

        }

      sum=dec2bin(n/2)*10+n%2;

    }

    return sum;

}

结果:

非递归:

源码:

#include<bits/stdc++.h>

//#include<iostream>

using namespace std;

stack<int> sta;

int main(){

      int n;

      while(cin>>n){

             while(!sta.empty()) sta.pop();

             if(n<0){

                    cout<<"-";

                    n=-n;

             }

             if(n==0){

                    puts("0");

                    continue;

             }

             while(n){

                    if(n&1) sta.push(1);

                    else sta.push(0);

                    n>>=1;

             }

             while(!sta.empty()){

                    cout<<sta.top();

                    sta.pop();

             }

             puts("");

      }

      return 0;

}

结果:

 

  1. 分别用递归法和非递归法求Fibonacci数列的前1000位,并比较计算时间的差异.

 

递归法:

源码:

#include<stdio.h>


//递归法

int fibonacci(int n)

{

      if(n<=0)

      {

             return 0;

      }

      if(n==1 || n==2)

      {

             return 1;

      }

      return fibonacci(n-1) + fibonacci(n-2);

}


int main(void)

{

      int n = 0,total=0;;

      int i = 1;

      int ret = 0;

      printf("输入要求的斐波拉契数列项数:");

      scanf("%d", &n);

      for(i=1;i<=n;i++)

      {

             ret = fibonacci(i);

             total = total + ret;

      //    printf("%d\n",ret);

      }

      //printf("第%d项 = %d\n",n,ret);

      printf("前%d项和 = %d\n",n,total);

      return 0;

}

结果:

非递归法:

源码:

#include<stdio.h>

int main()

{

      int n = 0,n_dis=0,total=0;

      int ret = 0;

      int bef1 = 1;

      int bef2 = 0;

      printf("输入要求的斐波拉契数列项数:");

      scanf("%d", &n);

      n_dis = n;

      while(n>0)

      {

             n = n - 1;

             bef2 = bef1;

             bef1 = ret;

             ret = bef1 + bef2;

             total = total + ret;

     

      }


      printf("前%d项和 = %d\n",n_dis,total);

      return 0;



}

结果:

  1. 递归算法完成如下问题:有52张牌,使它们全部正面朝上,第一轮是从第2张开始,凡是2的倍数位置上的牌翻成正面朝下;第二轮从第3张牌开始,凡是3的倍数位置上的牌,正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;第三轮从第4张牌开始,凡是4的倍数位置上的牌按上面相同规则翻转,以此类推,直到第一张要翻的牌超过52为止。统计最后有几张牌正面朝上,以及它们的位置号.

递归思想:

源码:

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

bool card[100];

void turn(int x)

{

if(x>52)return;

for(int i=x;i<=52;i+=x)

{

card[i]=!card[i];

}

turn(x+1);

}

int main()

{

memset(card,1,sizeof(card));

turn(2);

for(int i=1;i<=52;i++)

{

if(card[i])

cout<<i<<endl;

}

return 0;

} 

结果:

 

  1.  一个射击运动员打靶,靶一共有10环,连开6枪打中45环的可能性有多少种? (每一枪最少是0环,最多是10环)

思想:

源码:

#include <iostream>

using namespace std;

int sum;

int store[10];

void output()

{

     ++sum;

}


void compute(int score,int num)

{

  

    if(score<0||score>(num+1)*10)

        return;

 

    if(num==0)

    {

        store[num]=score;

        output();

        return;

    }

    for(int i=0;i<=10;++i)

    {

               store[num]=i;

        compute(score-i,num-1);

    }

}


int main()

{

    compute(45,5);

    cout<<"总数"<<sum<<endl;

    return 0;

}

结果:

  1.  在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,输出所有摆法。

 

分析:

1.想把8个皇后放进去,肯定最终每行只有一个皇后,每列只有一个皇后。

2.设个二维数组chess [ i ] [ j ] 模拟棋盘,cas存放摆法。i j 是表示i行j列:

写一个用于递归的函数,思路如下

3.从上往下一行行的放皇后,放下一行时从最左边(第0列)放起,如果不能放就往右挪一格再试。注意判断右边有没有越界出棋盘。

4.写一个函数专门判断当前位置能不能放,只需要判断该位置的横、竖、两对角线,这四条线上有没有其他皇后即可。命名为check。

5.如果把最后一行放完了,那就统计上这个摆法,cas++。摆完最后一行不能继续判断下一行了。

6.放完一种情况,还要探究其他情况,可以把现在放好的皇后“拿走”,然后再试探 之前没试探过的棋盘格。

7.拿走皇后操作可以和不能放皇后的操作用同样的代码实现:

如果这个位置不能放,要把它置零,表示没有皇后。

如果这位置能放,那就放皇后(置1)。等一种情况讨论完,还得把它拿开,“拿开”也是置零的操作。

所以应该想办法排列上述代码,保证已经把摆出的情况记录下来,之后执行“拿开皇后”代码。

源码:

#include<stdio.h>

#define line 8

void queen(int i,int j);

int check(int i,int j);

int chess[line][line];

int cas=0;

int xx,yy;

int main(){


   queen(0,0);

   printf("%d\n",cas);

   return 0;


}




void queen(int i,int j){


    if(j>=line){

         return ;

   }




if(check(i,j)==1){

     chess[i][j]=1;

     if(i==line-1){   

   cas++;

 

}


else{


     queen(i+1,0); }


}


      chess[i][j]=0;     queen(i,j+1);


}

int check(int i,int j){

     int k;

     for(k=0;k<line;k++){

         if(chess[i][k]==1) return 0;     }


for(k=0;k<line;k++){


       if(chess[k][j]==1) return 0;


}

for(k=-line;k<=line;k++){

      if(i+k>=0&&i+k<line&&j+k>=0&&j+k<line)      if(chess[i+k][j+k]==1) return 0;

      if(i-k>=0&&i-k<line&&j+k>=0&&j+k<line)      if(chess[i-k][j+k]==1) return 0;


}


      return 1;


} 

结果:

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值