算法设计与分析课后习题.docx

上传人:b****5 文档编号:28948880 上传时间:2023-07-20 格式:DOCX 页数:19 大小:177.34KB
下载 相关 举报
算法设计与分析课后习题.docx_第1页
第1页 / 共19页
算法设计与分析课后习题.docx_第2页
第2页 / 共19页
算法设计与分析课后习题.docx_第3页
第3页 / 共19页
算法设计与分析课后习题.docx_第4页
第4页 / 共19页
算法设计与分析课后习题.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

算法设计与分析课后习题.docx

《算法设计与分析课后习题.docx》由会员分享,可在线阅读,更多相关《算法设计与分析课后习题.docx(19页珍藏版)》请在冰豆网上搜索。

算法设计与分析课后习题.docx

算法设计与分析课后习题

1、实验内容递归

求n的二次方各项的系数。

2、程序设计

代码如下:

#include"stdio.h"

voidcoeff(inta[],intn)

{

if(n==1)

{

a[1]=1;a[2]=1;

}

else

{

coeff(a,n-1);

a[n+1]=1;

for(inti=n;i>=2;i=i-1)

a[i]=a[i]+a[i-1];

a[1]=1;

}

}

voidmain()

{

inta[100],i,n;

printf("输入n的值:

");

scanf("%d",&n);

coeff(a,n);

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

printf("%d",a[i]);

printf("\n");

}

3、运行结果

1、实验内容

写出计算ackerman函数ack(m,n)的递归计算函数。

2、程序设计

代码如下:

#include"stdio.h"

intack(intm,intn)

{

if(m==0)

returnn+1;

elseif(n==0)

returnack(m-1,1);

else

returnack(m-1,ack(m,m-1));

}

voidmain()

{

intm,n,z;

printf("inputmandn:

");

scanf("%d%d",&m,&n);

if(m<0&&n<0)

printf("errorinput!

");

else

z=ack(m,n);

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

}

3、运行结果

 

第四章

例15求数列的最大子段和

给定n个元素的整数列(可能为负整数)a1,a2,…..,an。

求形如:

ai,ai+1,……aji,j=1,…..,n,i<=j

的子段,使其和为最大。

当所有整数均为负整数时定义其最大子段和为0.

程序:

#include

intmaxsum2(inta[],intleft,intright)

{

intcenter,i,left_sum,right_sum,s1,s2,lefts,rights;

if(left==right)

if(a[left]>0)

returna[left];

else

return0;

else

{

center=(left+right)/2;

left_sum=maxsum2(a,left,center);

right_sum=maxsum2(a,center+1,right);

s1=0;

lefts=0;

for(i=center;i>=left;i--)

{

lefts=lefts+a[i];

if(lefts>s1)

s1=lefts;

}

s2=0;

rights=0;

for(i=center+1;i<=right;i++)

{

rights=rights+a[i];

if(rights>s2)

s2=rights;

}

if((s1+s2

returnleft_sum;

if(s1+s2

returnright_sum;

return(s1+s2);

}

}

intmaxsum1(inta[],intn)

{

return(maxsum2(a,1,n));

}

voidmain()

{

inta[100],n;

printf("enteranumber:

");

scanf("%d",&n);

printf("enterthenumberofa[]:

");

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

scanf("%d",&a[i]);

printf("%d",maxsum1(a,n));

printf("\n");

}

运行结果:

 

回溯法

N皇后问题

例如:

8皇后问题:

要在8×8的国际象棋棋盘中放8个皇后,使任意两个皇后都不能互相吃掉。

规则是皇后能吃掉同一行、同一列、同一对角线的任意棋子。

下图为一种方案,求所有的解。

0

0

0

0

0

0

0

0

模型建立:

不妨设8个皇后为xi,他们分别在第i行(i=1,2,3,4,5,6,7,8),这个问题的解空间,就是一个8个皇后所在的序号,为n元一维向量(x1,x2,x3,x4,x5,x6,x7,x8),搜索空间是1<=xi<=8(i=1,2,3,4,5,6,7,8),共88个状态。

约束条件是8个点(1,x1),(2,x2),(3,x3),(4,x4),(5,x5),(6,x6),(7,x7),(8,x8)不在同一列和同一对角线上。

算法设计:

用回溯法从开始结点出发,以深度优先的方式搜索整个解空间。

这个开始结点就成为一个活结点,同时也成为当前的扩展结点。

在当前的扩展结点出,搜索向纵深方向移动至一个活结点。

这个新结点就成为一个新的活结点,并成为当前扩展结点。

如果在当前的扩展结点出不能再向纵深方向移动,则当前扩展结点就成为死结点。

此时,应往回移动(回溯)至最近的一个活结点处,病史这个活结点成为当前的扩展结点。

回溯法即以这种工作方式递归的在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。

程序设计:

#include

#include

voidbackdate(intn);

intcheck(intk);

inta[20],n;

voidmain()

{

printf("PleaseinputanumberN>3:

\n");

scanf("%d",&n);

backdate(n);

}

 

voidbackdate(intn)

{

intk;

a[1]=0;

k=1;

while(k>0)

{

a[k]=a[k]+1;

while((a[k]<=n)&&(check(k)==0))

a[k]=a[k]+1;

if(a[k]<=n)

if(k==n)

{inti;

printf("%d皇后的解为:

\n",n);

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

printf("%d\n",a[i]);

}

else

{

k++;

a[k]=0;

}

else

k--;

}

}

intcheck(intk)

{

inti;

for(i=1;i<=k-1;i++)

if((abs(a[i]-a[k])==abs(i-k))||(a[i]==a[k]))

return(0);

return

(1);

}

运行结果:

 

例12狱吏问题

算法1

程序:

#include

#include

voidmain()

{

int*a,i,j,n;

scanf("%d",&n);

a=(int*)calloc(n+1,sizeof(int));

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

a[i]=1;

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

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

a[j]=1-a[j];

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

if(a[i]==0)

{

printf("%disfree.",i);

printf("\n");

}

}

运行结果:

算法2

程序:

#include

voidmain()

{

ints,i,j,n;

scanf("%d",&n);

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

{

s=1;

for(j=2;j<=i;j++)

if(i%j==0)

s=s+1;

if(s%2==1)

{

printf("%disfree.",i);

printf("\n");

}

}

}

运行结果:

 

算法3

程序:

#include

voidmain()

{

inti,n;

scanf("%d",&n);

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

if(i*i<=n)

{

printf("%disfree.",i*i);

printf("\n");

}

else

break;

}

运行结果:

 

贪婪法

例4.22货币统计问题

某单位给每个职工发工资(精确到元)。

为了保证不要临时兑换零钱,且取款的张数最少,取工资前要统计出所有职工的工资所需各种币值(100,50,20,10,5,2,1共7种)的张数,请编程完成。

源程序如下:

#include"stdio.h"

voidmain(){

inti,j,n,GZ,A,B[8]={0,100,50,20,10,5,2,1},S[8]={0,0,0,0,0,0,0,0};

printf("请输入人数:

");

scanf("%d",&n);

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

printf("输入工资:

");

scanf("%d",&GZ);

for(j=1;j<=7;j=j+1){

A=GZ/B[j];

S[j]=S[j]+A;

GZ=GZ-A*B[j];

}

}

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

printf("币值%5d,张数%5d\n",B[i],S[i]);

}

运行结果:

习题4.3

问题描述:

54张扑克牌,两人轮流拿,每人每次最少拿一张,最多纳四张,谁拿最后一张谁输。

编写模拟计算机先拿牌且必胜的算法。

原代码如下:

#include

main()

{

inti,a[10];

printf("甲4\n");

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

{

scanf("%d",&a[i]);

if(a[i]>=1&&a[i]<=4)

{

printf("\n乙%d\t甲%d\n",a[i],5-a[i]);

}

else

{

printf("\n你输入的数据有误\n");

return0;

}

}

printf("甲胜\n");

}

运行结果:

 

资源分配

#include

voidmain()

{

inti,j,k,m,n,rest;

inta[100][100],gain[100];

floatq[100],f[100],temp[100];

printf("Howmanyitem?

");scanf("%d",&m);

printf("Howmuchmoney?

");scanf("%d",&n);

printf("inputgaintable:

");

for(j=0;j<=n;j++)

{

scanf("%f",&q[j]);

f[j]=q[j];

}

for(j=0;j<=n;j++)

a[1][j]=j;

for(k=2;k<=m;k++)

{

printf("inputanotheritemgaintable\n");

for(j=0;j<=n;j++)

{

temp[j]=q[j];

scanf("%f",&q[j]);

a[k][j]=0;

}

for(j=0;j<=n;j++)

for(i=0;i<=j;i++)

if(f[j-i]+q[i]>temp[j])

{

temp[j]=f[j-i]+q[i];

a[k][j]=i;

}

for(j=0;j<=n;j++)

f[j]=temp[j];

}

rest=n;

for(i=m;i>=1;i--)

{

gain[i]=a[i][rest];

rest=rest-gain[i];

}

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

printf("第%d个项目分配资源%d\n",i,gain[i]);

printf("最大利润为%f\n",f[n]);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1