《算法设计与分析》考前复习编程题篇

经典算法问题

【1】猴子爬山问题——递推算法

猴子每次爬 1 级或 2 级台阶,有多少种不同的方法爬20级能到达楼顶呢?
(1)给出爬梯子问题的状态转换方程
解:由题意得:
f(20) = f(19) + f(18)
f(19) = f(18) + f(17)

f(2) = 2
f(1) = 1
所以状态转换方程为:f(n) = f(n-1) + f(n-2 )
(2)给出基于状态转换方程的递推实现

int c(int n) {
    int i;
    if (n==1||n==2){
        return n;
    }
    for(i=2;i<n;i++){
        f[i]=f[i-1]+f[i-2];
    }
    return f[n-1];
}

程序源代码:

#include <stdio.h>
#include <stdlib.h>

int f[20];
int main(){
    int i,j;
    f[0] = 1;
    f[1] = 2;
    for(i=0;i<20;i++){
            if(i%5==0)
            printf("\n");
        printf("%4d  ",c(i));

    }
    printf("\n猴子爬到第%d阶有%d种",i,c(i));
}
int c(int n) {
    int i;
    if (n==1||n==2)
        return n;
	for(i=2;i<n;i++)
        f[i]=f[i-1]+f[i-2];
	return f[n-1];
}

程序运行截图:
在这里插入图片描述
【2】N皇后问题——回溯算法
设计回溯算法,解决四皇后问题(在4×4的方格棋盘上放置4个皇后使它们互不攻击),要求能输出回溯的过程。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main() {
    int g,k,j,x,a[5]= {0,1,0,0,0},i=1,s=0;
    while (1) {
        g=1;
        for(k=i-1; k>=1; k--) {
            x=abs(a[i]-a[k]);
            if(x==0 || x==i-k) g=0;
        }
        if(i==4 && g==1) {
            for(j=1; j<=4; j++)
                printf("%4d",a[j]);
            printf("\n");
            s++;
        }
        if(i<4 && g==1) {
            i++;
            a[i]=1;
            continue;
        }
        while(a[i]==4 && i>1)
            i--;
        if(i==1&&a[i]==4)
            break;
        else
            a[i]=a[i]+1;
    }
    printf("\n  共%d个解.\n",s);
}

运行程序结果:
在这里插入图片描述
【3】最大路径和问题——动态规划算法
给定一个矩阵m如下图,从左上角开始每次只能向右走或者向下走,最后达到右下角的位置,路径中所有数字累加起来就是路径和,求出所有路径的最大路径和。
在这里插入图片描述
源代码:

#include <stdio.h>
#include <stdlib.h>

    int main() {
    int a[4][4]= {1,3,5,9,
                  8,1,3,4,
                  5,0,6,1,
                  8,8,4,0};
    int dp[4][4];	//存放决策表(最短路径状态矩阵)
    int i,j;
    //边界条件问题需要考虑到
    dp[0][0]=a[0][0];  //左上角(i==0&&j=0)
    for (j=1; j<4; j++)
        dp[0][j]=a[0][j]+dp[0][j-1];//初始化上沿线(i==0&&j!=0)
    for (i=1; i<4; i++)
        dp[i][0]=a[i][0]+dp[i-1][0];//初始化左沿线(i!=0&&j==0)
    for (i=1; i<4; i++)  	      //遍历计算到达各点的最短路径值
        for (j=1; j<4; j++)
            dp[i][j]=a[i][j]+(dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1]);
    for (i=0; i<4; i++) {
        for (j=0; j<4; j++)
            printf("%4d",dp[i][j]);
        printf("\n");
    }
}

程序运行截图:
在这里插入图片描述
【4】韩信点兵问题——枚举算法
韩信先令士兵从1-3报数,结果最后一个士兵报2;从1-5报数,最后一个士兵报3,;从1-7报数,最后一个士兵报4.用C语言编写程序计算士兵总数至少有多少人?

源程序:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i=1;
    while(i<1000){
        if(i%3==2&&i%5==3&&i%7==4)
            printf("%d\n",i);
    i++;


       }
    return 0;
}

程序运行结果:在这里插入图片描述

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程饱饱吃得好饱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值