c语言蟠桃记编程,SDUT 2019 级程序设计基础(B)II 实验3--递推

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

总题目链接

3-1养兔子

#include

#include

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;

}

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

b4750b1f28f07d1f3dafe6bf15999bef.png

下面兔子都以对为单位,可以看出第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

#include

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

#include

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

#include

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

#include

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

#include

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

#include

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

#include

int main()

{

int t;

double h,n;

scanf("%d",&t);

while(t--)

{

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

#include

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

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

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<

return 0 ;

}

小结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值