SDUT 2019 级程序设计基础(B)II 实验3–递推

快期末了 好久没用过C,重新打一下程设二的内容找找手感,顺便水几篇博客,简单题直接过,需要思考的会有注释或者思路,重要知识点会总结,祝大家期末都AK!!!
总题目链接

3-1养兔子

#include <stdio.h>
#include <stdlib.h>
long long sum[100];

void getfibo()//直接预处理把1-90天都算出来(因为n<=90)
{
    sum[1]=1;
    sum[2]=2;
    for(int i=3;i<=90;i++)
        sum[i]=sum[i-1]+sum[i-2];
}

int main()
{
    int n;
    getfibo();
    while(~scanf("%d",&n)&&n)
    {
        printf("%lld\n",sum[n]);
    }

    return 0;
}

此题就是一个典型斐波那契数列,如下:

在这里插入图片描述

下面兔子都以对为单位,可以看出第n天出生的是由第n-1天成年的和第n-1天新生的兔子(长大一天第n天可以生了)一起生的,而第n-1天出生的又由有第n-2天出生和成年的一起生的……如此递推,很容易得出第i天出生的兔子数:1 1 2 3 5……,同理总兔子数也可以求得为 1 2 3 5 8…即斐波那契数列。

3-2 母牛的故事

思路:

当年数小于等于4的时候,第几年就是有几头牛,当n=5的时候,这时候第一年出生的那个小母牛就也可以生出小母牛了,可得,第n-3年有多少头母牛,到了第n年这些牛都能生小牛了,因此出生数为a[n-3],从而可以得到今年的母牛数为:
a[n] = a[n-1]+a[n-3],

#include <stdio.h>
#include <stdlib.h>
long long a[100];

void getfibo()
{
    a[1]=1;
    a[2]=2;
    a[3]=3;
    for(int i=5;i<=55;i++)
        a[i]=a[i-1]+a[i-3];
}
int main()
{
    int n;
    getfibo();
    while(~scanf("%d",&n)&&n)
    {
        printf("%lld\n",a[n]);
    }

    return 0;
}

3-3鬼吹灯之龙岭迷窟

#include <stdio.h>
#include <stdlib.h>
long long a[100];

void getfibo()
{
    a[1]=5;
    a[2]=8;
    for(int i=3;i<=20;i++)
        a[i]=a[i-1]+a[i-2];
}

int main()
{
    int n;
    getfibo();
    while(~scanf("%d",&n)&&n)
    {
        printf("%lld\n",a[n]);
    }

    return 0;
}

3-4骨牌铺方格

课本讲的挺详细了,其实也是个斐波那契数列

#include <stdio.h>
#include <stdlib.h>
long long a[100];

void getfibo()
{
    a[1]=1;
    a[2]=2;
    for(int i=3;i<=50;i++)
        a[i]=a[i-1]+a[i-2];
}

int main()
{
    int n;
    getfibo();
    while(~scanf("%d",&n)&&n)
    {
        printf("%lld\n",a[n]);
    }
    return 0;
}

3-5爬楼梯

巧合的是这题代码和上一题一模一样,因为本质也是骨牌铺方格。
因为一次只能走1级或2级,当n>2时,要走到第n级,那么前一步肯定是走1级或者2级,所以走到第n级的方法次数就是a[n-1]+a[n-2]。

#include <stdio.h>
#include <stdlib.h>
long long a[100];

void getfibo()
{
    a[1]=1;
    a[2]=2;
    for(int i=3;i<=50;i++)
        a[i]=a[i-1]+a[i-2];
}

int main()
{
    int n;
    getfibo();
    while(~scanf("%d",&n)&&n)
    {
        printf("%lld\n",a[n]);
    }
    return 0;
}

3-6三国佚事——巴蜀之危

书上讲的很明白啦

#include <stdio.h>
#include <stdlib.h>
long long a[100];

void getfibo()
{
    a[1]=0;
    a[2]=1;
    for(int i=3;i<=20;i++)
        a[i]=(i-1)*(a[i-1]+a[i-2]);
}

int main()
{
    int n;
    getfibo();
    while(~scanf("%d",&n))
    {
        printf("%lld\n",a[n]);
    }
    return 0;
}

3-7王小二切饼

思路

第n刀最多能和前面的n-1条线全部相交产生n个交点,划过n个面,所以能新增n个,加上原来的即a[n-1],得递推:a[n]=n+a[n-1];

#include <stdio.h>
#include <stdlib.h>
long long a[100];

void getfibo()
{
    a[1]=2;
    for(int i=2;i<=100;i++)
        a[i]=a[i-1]+i;
}

int main()
{
    int n;
    getfibo();
    while(~scanf("%d",&n))
    {
        printf("%lld\n",a[n]);
    }
    return 0;
}

3-8 C语言实验——拍皮球

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

int main() {
    double h, n;
    scanf("%lf %lf", &h, &n);
    double ans = h;
    n--;
    h /= 2;
    while (n--) {
        ans += h * 2;
        h /= 2.0;
    }
    printf("%.2f %.2f\n", ans, h);
    return 0;
}

3-9蟠桃记

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

int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        n--;
        int ans=1;
        while(n--)
        {
            ans=(ans+1)*2;
        }
        printf("%d\n",ans);
    }
    return 0;
}

3-10马拦过河卒

1.递推做法

其实可以类比上面题目的走楼梯,要走到(x,y)有两种方式,即从左边和从上面走过来,容易得到递推式,写出代码,要注意的是边界判断和马的判断。

#include<stdio.h>
int main()
{
    int dx[9]={0,-2,-1,1,2,2,1,-1,-2};
    int dy[9]={0,1,2,2,1,-1,-2,-2,-1};
    int m ,  n , x, y,i , j ;
    long long int f[20][20]={0};
    int g[20][20]={0};
    scanf("%d %d %d %d",&n,&m,&x,&y);
    g[x][y]=1;
    for(i=1;i<=8;i++)
        if(x+dx[i]>=0&&x+dx[i]<=n&&y+dy[i]>=0&&y+dy[i]<=m)
                g[x+dx[i]][y+dy[i]]=1;
        for(i=1;i<=n;i++)
        {
            if(g[i][0]!=1)
                f[i][0]=1;
            else
            for(;i<=n;i++)
            {
                f[i][0]=0;
            }
        }
        for(j=1;j<=m;j++)
        {
            if(g[0][j]!=1)
                f[0][j]=1;
            else
            for(;j<=m;j++)
                f[0][j]=0;
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(g[i][j]==1)
                f[i][j]=0;
                else
                f[i][j]=f[i-1][j]+f[i][j-1];
            }
        }
        printf("%lld\n",f[n][m]);
        return 0;
}

2.DFS&BFS

学完图论后会学到dfs和bfs,感兴趣可以研究,不展开讨论

#include<bits/stdc++.h>

using namespace std;

int mmp[100][100] ;//棋盘
int vis[100][100] ; //标记变量
int step  = 0 ; //记录路径数
int a ,b ,n , m ;
int next1[9][2]={0,0,-2,1,2,1,-2,-1,2,-1,1,2,1,-2,-1,-2,-1,2}; //马的走动方式

void dfs(int x , int y)
{
    int i ;
    int next[2][2] = {{0,1},{1,0}} ; //卒的走动方式,卒无法向上走,也无法向右走
    int tx ,ty ;
    if(x==n&&y==m)
        step++ ;
    for(i=0;i<2;i++)
    {
        tx = x + next[i][1] ;
        ty = y + next[i][0] ;
        if(tx<0 || tx>n || ty < 0 || ty > m)
            continue ;
        if(!vis[tx][ty]&&mmp[tx][ty])
        {
            vis[tx][ty] = 1 ;
            dfs(tx,ty)  ;
            vis[tx][ty] = 0 ;
        }

    }
}

int main()
{
    int i ;
    cin>>n>>m>>a>>b ; //a,b是马的坐标。
    memset(vis,0,sizeof(vis)) ;
    memset(mmp,1,sizeof(mmp)) ; //先假设棋盘上没有马
    for(i=0;i<=8;i++)
    {
        if(a+next1[i][0]>=0&&a+next1[i][0]<=n&&b+next1[i][1]>=0&&b+next1[i][1]<=m)
        {
            mmp[a+next1[i][0]][b+next1[i][1]] = 0 ; //马的阻挡,卒无法通过。
        }
    }
    vis[0][0] = 1 ;
    dfs(0,0) ;
    cout<<step<<endl ;
    return 0 ;
}

小结

递推本质就是找规律,需要运用思维,只能靠多练多体会多理解(当然期末考试背背规律也能应付过去)

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇