多种解法求百钱百鸡问题
PYTHON中百钱买百鸡问题
PYTHON中百钱买百鸡问题PYTHON中百钱买百鸡问题问题:中国古代数学家张丘建在他的《算经》中提出了⼀个著名的“百钱买百鸡问题”:鸡翁⼀,值钱五;鸡母⼀,值钱三;鸡雏三,值钱⼀;百钱买百鸡,问翁、母、雏各⼏何?在PYTHON中编程实现将所有可能的⽅案输出。
问题分析:根据题意设公鸡、母鸡和雏鸡分别为cock,hen和biddy,如果100钱全买公鸡,那么最多能买20只,所以cock的范围是⼤⼩等于0⼩于等于20;如果全买母鸡那么最多能买33只,所以hen的范围是⼤于等于0⼩于等于33;如果100钱全买⼩鸡,那么根据题意最多能买99只(⼩鸡的数量应⼩于100且是3的倍数)。
在确定了各种鸡的范围后进⾏穷举并判断,判断的条件有以下3种:(1)、所买的三种鸡的钱数总和为100;(2)、所买的三种鸡的数量之和为100;(3)、所买的⼩鸡的数量必须是3的倍数。
程序代码:for cock in range(0,20+1): #鸡翁范围在0到20之间for hen in range(0,33+1): #鸡母范围在0到33之间for biddy in range(3,99+1): #鸡雏范围在3到99之间if (5*cock+3*hen+biddy/3)==100:#判断钱数是否等于100if (cock+hen+biddy)==100: #判断购买的鸡数是否等于100if biddy%3==0: #判断鸡雏数是否能被3整除print ("鸡翁:",cock,"鸡母:",hen,"鸡雏:",biddy) #输出程序运⾏结果:鸡翁: 0 鸡母: 25 鸡雏: 75鸡翁: 4 鸡母: 18 鸡雏: 78鸡翁: 8 鸡母: 11 鸡雏: 81鸡翁: 12 鸡母: 4 鸡雏: 84。
c++、python、vb求解百钱百鸡问题
我国古代数学家张丘建在《算经》一书中曾提出过著名的“百钱买百鸡”问题,该问题叙述如下:鸡翁一,值钱三;鸡母一,值钱二;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?翻译过来,意思是公鸡一个三块钱,母鸡一个二块钱,小鸡三个一块钱,现在要用一百块钱买一百只鸡,问公鸡、母鸡、小鸡各多少只?题目分析如果用数学的方法解决百钱买百鸡问题,可将该问题抽象成方程式组。
设公鸡x 只,母鸡y 只,小鸡z 只,得到以下方程式组:A:3x+2y+1/3z = 100B:x+y+z = 100C:0 <= x <= 100D:0 <= y <= 100E:0 <= z <= 100如果用解方程的方式解这道题需要进行多次猜解,因此我们用穷举法的方式来解题。
1.C++语言#include<iostream>using namespace std;int main(){int i,j,k,x,y,z;for (i=0;i<=33;i++)for(j=0;j<=50;j++)for(k=0;k<=100;k++)if((3*i+2*j+k/3==100)&&(i+j+k==100)&&k%3==0)cout<<i<<" "<<j<<" "<<k<<endl;return 0;}2.Python语言for i in range(33):for j in range(50):for k in range(100):if (3*i+2*j+k/3==100) and (i+j+k==100) and (k%3==0):print(i,j,k)3.VB语言Dim a As Integer, b As Integer, c As IntegerFor a = 0 To 33For b = 0 To 50For c = 0 To 100If 3 * a + 2 * b + 1 / 3 * c = 100 And a + b + c = 100 ThenPrint "公鸡" & a, "母鸡" & b, "小鸡" & cEnd IfNext cNext bNext a。
百钱百鸡问题
百鸡问题
公元5世纪末,我国古代数学家张丘建在他所撰写的《算经》中,提出了这样的一个问题:“鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一.百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?”意思是公鸡5元一只,母鸡3元一只,小鸡1元三只。
用100元100只鸡,求公鸡、母鸡、小鸡各买几只。
假设a 为公鸡只数,b 为母鸡只数,c 为小鸡只数,如果把问题转化为n 元钱买n 只鸡,针对上述问题n =100,根据题意可得出下面的约束方程:
53/3%30
a b c n
a b c n c ++=++==
用穷举法实现如下所示:
图4.3 穷举法求解百鸡问题
这个算法有三重循环,枚举公鸡数量的外循环,枚举母鸡数量的中间循环以及枚举小鸡数量的内循环,主要执行时间取决于内循环的循环体的执行次数,需要执行(n+1)3次,当n=100时,内循环需要执行大于100万次。
考虑到n元钱只能买到n/5只公鸡或n/3只母鸡,因此有些组合可以不必考虑,而小鸡的数目又取决于公鸡和母鸡的只数,上述的内循环可以省去。
图4.3 改进算法求解百鸡问题
改进算法只有两层循环,枚举公鸡数量的外循环和枚举母鸡数量的内循环,内循环的执行次数为(n/5+1) (n/3+1)。
当n=100时,内循环执行21*34=714次,这和穷举算法的100万次相比,仅为原来的万分之七,有重大改进。
“百鸡问题”的两种解法
教学争鸣新课程NEW CURRICULUM“百鸡问题”的两种解法常煜(河北唐山市第12中学)很多人在理解数学时遇到了困难,便为自己找借口说:“数学太抽象了。
”其实,数学再抽象也是来源于我们的生活,只要用一种正确的态度和思想来对待它,它就会变得很容易。
在全面推进素质教育的今天,如何寓教于乐,有效地激发学生的学习兴趣和主动学习的能力尤为重要,本文试图通过利用计算机Visual FoxPro编程来解决数学中的一个传统的题目,给学生介绍一种用计算机快速求解数学问题的方法,以提高数学教学的生动性、趣味性。
我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。
百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?首先我们用普通数学方法解答如下:解:根据题目知道公鸡五文一只,而现在百钱买百鸡(100文钱买鸡),所以公鸡数量要最多为20。
设:母鸡M只,公鸡N只,小鸡100-M-N只,所以5N+3M+(100-M-N)/3=100且M,N为整数,所以可以得出正确答案:有三种情况:公鸡4只,母鸡18只,小鸡78只;公鸡8只,母鸡11只,小鸡81只;公鸡12只,母鸡4只,小鸡84只。
这道题其逻辑性正好与计算机程序性非常吻合,如果利用计算机Visual FoxPro编程来解这个问题,我们只要编写好程序,计算机就会很快计算出来,而且在变换其他数据组时也会很容易得到答案。
用Visual FoxPro编程如下:Cleagj=1xh=1do while gj<=20&&买公鸡的最大数mj=1do while mj<=33&&买母鸡的最大数xj=1do while xj<=100&&买小鸡的最大数if(5*gj+3*mj+xj/3)=100.and.(gj+mj+xj)=100?space(10)+str(xh)+'公鸡=',gj??space(10)+str(xh)+'母鸡=',mj??space(10)+str(xh)+'小鸡=',xj?xh=xh+1endifxj=xj+1enddomj=mj+1enddogj=gj+1enddo结果有三组:A:(4,18,78)B:(8,11,81)C:(12,4,84)数学是一种科学、一种语言、一种艺术、一种思维方法,是学校教育中永恒并且最重要的部分之一,要让学生学好数学,首先必须让学生发现数学中的美之所在,对数学感兴趣。
百钱买百鸡实验报告
一、题目描述我国古代数学家张丘建在《算经》一书中曾提出过著名的“百钱买百鸡”问题,该问题叙述如下:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?翻译过来,意思是公鸡一个五块钱,母鸡一个三块钱,小鸡三个一块钱,现在要用一百块钱买一百只鸡,问公鸡、母鸡、小鸡各多少只?二、解题思路对n=100的情况,因为有三个变量,则有三重循环和二重循环两种算法1、算法一:三重循环(1)变量变化范围的确定:由于公鸡5钱一只,则100钱最多可购买100/5=20只公鸡,此即为第一个变量的变化上限;由于母鸡3钱一只,则100钱最多可购买100/3≈33只母鸡,此即为第二个变量的变化上限;由于小鸡三只一钱,而所有鸡的总数不得超过100只,则100即为第三个变量的变化上限;(2)条件的控制:由百钱买百鸡可知,鸡的数量为100只,买鸡所用的钱数为100钱,即控制条件为a+b+c=100且a*5+b*3+c/3=100;2、二重循环:(1)变量变化范围的确定:由于整题共有3个变量,所以当前两个变量确定后,第三个变量自然被确定下来,故可采用二重循环解题。
前两个变量的确定同三重循环,第三个变量则用c=n-a-b来确定;(2)条件的控制:由百钱买百鸡可知,鸡的数量为100只,买鸡所用的钱数为100钱,即控制条件为a+b+c=100且a*5+b*3+c/3=100;由于需要讨论算法的时间性能,在程序中加入时间函数计算程序运行所需的时间进行比较。
用控制变量的方法,对两种算法中的n进行同样的变化处理,来讨论两种算法的时间性能,e.g.分别令n=100,n=200,n=500,n=1000,n=2000,n=5000三、自我评估、反思由于较长时间未使用C语言编程,所以在使用语法上略显生疏了些,通过这次作业的实践过程,对C语言的编程语法规则熟悉了许多,虽然在运行过程中出现了一些错误,但也都能够较快地解决,第一次的数据结构实验作业总体完成的还算比较顺利。
百鸡问题答案
百鸡问题答案【篇一:百鸡问题】,值钱伍;鸡母一,值钱三;鸡鶵三,值钱一。
凡百钱买鸡百只,问鸡翁、母、鶵各几何?答曰:鸡翁四,值钱二十;鸡母十八,值钱五十四;鸡鶵七十八,值钱二十六。
又答:鸡翁八,值钱四十;鸡母十一,值钱三十三,鸡鶵八十一,值钱二十七。
又答:鸡翁十二,值钱六十;鸡母四、值钱十二;鸡鶵八十四,值钱二十八。
”原书说明这个问题流传很广,解法很多,但从现代数学观点来看,实际上是一个求不定方程整数解的问题。
解法如下:设公鸡、母鸡、小鸡分别为x、y、z 只,由题意得:①……x+y+z =100②……5x+3y+(1/3)z =100x =12;y =4;z =84c语言解法#include stdio.hvoid main(){int cocks=0,hens,chicks;while(cocks=20){: k s; q# s1 m4 nhens=0;while(hens=33){( e2 n/ \) `9 t% e* f( r6 xchicks=100-cocks-hens;if(5.0*cocks+3.0*hens+chicks/3.0==100.0)1 t0 g4 {+ e c: h9 n/a8 y printf(公鸡%d只,母鸡%d只,小鸡%d只\n\n,cocks,hens,chicks); hens++;}cocks++;}}输出结果为:公鸡0只,母鸡25只,小鸡75只公鸡4只,母鸡18只,小鸡78只公鸡8只,母鸡11只,小鸡81只公鸡12只,母鸡4只,小鸡84只java语言解法public class baijiwenti4 c. m0 i k! }/ m/ n z{0 t4 j8 f0 q n: j: z4 b; ipublic static void main (string [] args)+ b6 t s2 i/ e c: c{for (int x = 0; x = 19; x++){2 z) l8 q% x% @( s$ sfor (int y = 0; y = 33; y++)7 h6 r5 ^ w# t9 l{, b7 d4 q7 `) z2 k i% n7 [int z = 100 - x - y;if((x * 5 + y * 3 + z / 3 == 100 ) z % 3 == 0){# h1 q. t( j/ s y/ r, ssystem.out.println(可买鸡翁只数: + x);system.out.println(可买鸡母只数: + y);system.out.println(可买鸡雏只数: + z);/ r8 f+ ? b4 ? q4 | r}/ c$ u/ w7 k8 {+ h7 d}}}}【篇二:著名数学难题赏析-百钱百鸡】p class=txt>数学教研组(共两课时120分钟)我国古代数学书《张邱建算经》中有如下问题,也就是著名的百鸡百钱问题。
第十五节拓展资源-百钱百鸡和百元百畜解答比较
“百钱百鸡问题”和“百元百畜问题”解答比较张丘建是我国南北朝时期著名的数学家,他于公元5-6世纪所著的《张丘建算经》是后世通称的算经十书之一。
书中最后一个问题就是流传至今的“百钱百鸡”问题:今有鸡翁一,值钱伍;鸡母一,值钱三;鸡雏三,值钱一。
凡百钱买鸡百只,问鸡翁、母、雏各几何?用现在的语言解解释就是:公鸡每只值五文钱,母鸡每只值三文钱,小鸡每三只值一文钱。
现在用一百文钱买一百只鸡,问:一百只鸡中,公鸡、母鸡、小鸡各有多少只?该问题之所以饮誉海内外,是因为它导致了三元不定方程组,而张丘建是世界上第一个给出一题多解的人,他解算“百钱百鸡”问题的方法也是当时世界上最简捷先进的。
书中只有15个字的解法:“鸡翁每增四,鸡母每减七,鸡雏每益三,即得”。
原来张丘建是这样解答的,设公鸡、母鸡、小鸡各有x、y、z只,显然它们都是正整数,则根据题意,可得方程组先把x看成常数,这样可得为了得到整数解,令x=4t,可得一组解:x=4t, y=25-7t, z=75+3t,由于y=25-7t 中对t的限制,t只能取1,2,3三个值,可得三组解:公鸡有4只,母鸡18只,小鸡78只;公鸡有8只,母鸡11只,小鸡81只;公鸡有12只,母鸡4只,小鸡84只。
从这个结果就可看出张丘建“鸡翁每增四,鸡母每减七,鸡雏每益三”的解答奥妙。
无独有偶,瑞士著名数学家欧拉也曾研究过类似的问题。
这是因为欧拉非常重视方程,他写的《代数学原理》有许多关于方程的重要论述。
下面就是欧拉所出的一道“百元百畜”问题:某人用100元买了猪、山羊和绵羊共100只,其中猪7/2元一只,山羊4/3元一只,绵羊1/2元一只,问各买了多少只?这个问题与“百钱百鸡问题”极为相似,但晚了一千多年。
欧拉采用了“盲人法则”解答此题,这个“盲人法则”与张丘建解“百钱百鸡问题”的方法也很相似,现介绍如下:设猪、山羊和绵羊的数目分别是x,y,z,显然它们都是正整数,可得方程组:把x暂时看作常数移到符号右端,可得关于y和z的方程组:令x=5t,则x=5t, y=60-18t, z=40+13t,由于y=60-18t中对t的限制,t只能取1,2,3三个值,可得三组解:猪有5只,山羊有42只,绵羊53只;猪有10只,山羊有24只,绵羊66只;猪有15只,山羊有6只,绵羊79只。
小学奥数百鸡问题详解
小学奥数百鸡问题详解百鸡问题,现代数学用不定方程求解,在小学阶段,不少同学都是用拼凑的办法来解决。
这里介绍一种新方法,对小学生很适用《张丘建算经》中有这样一题:公鸡每只值5文钱,母鸡每只值3文钱,小鸡每3只值1文钱。
现在用100文钱买100只鸡,公鸡、母鸡、小鸡各有多少只?这是中国古代算术中的一类典型问题百鸡问题,现代数学用不定方程求解,在小学奥数题解题中,不少同学都是用拼凑的办法来解决。
这里介绍一种新方法,对小学生很适用。
1、求倍数。
每只公鸡值5文钱,每只母鸡值3文钱,每只小鸡值1/3文钱。
以最便宜的小鸡为标准,公鸡和母鸡的价格分别是小鸡的51/3=15倍和31/3=9倍。
2、算超额。
假设100文钱全部买小鸡,可买1001/3=300只,超出实有三种鸡总数300-100=200只。
3、组等式。
由于公鸡置换成小鸡可多出自身只数的15-1=14倍,母鸡置换成小鸡可多出自身只数的9-1=8倍。
不难理解,上述假设中多出的200只即为公鸡和母鸡置换成小鸡后一共增加的只数,关系式为:公鸡只数14+母鸡只数8=200.4、试结果。
一般来说,不定方程的正整数解按关系式就可以观察得到。
我们也可以先把等式变形,观察起来更为容易。
方法是,在等式两边同时除以一个相同的数(0除外),得到等式右边为整数,左边只有一项系数是分数的形式。
在上式两边同时除以8,得到:公鸡只数7/4+母鸡只数=25.显然,公鸡只数必须是4的倍数。
这样,从4 起,依次用4的倍数去试算,可以得出三种情况:公鸡4只,母鸡18只,小鸡78只;或公鸡8只,母鸡11只,小鸡81只;或公鸡12只,母鸡4只,小鸡84只。
下面再举一例来验证。
大数学家欧拉曾提出过这样的问题:一头猪321(31 2)银币,一只山羊131(11 3)银币,一只绵羊21(1/2)银币。
有人用100个银币,买了100头牲畜。
问:猪、山羊、绵羊各多少?猪的单价是绵羊的31 21/2=7倍,山羊的单价是绵羊的11 31/2=22 3倍,猪和山羊分别置换成绵羊,可多出自身只数的7-1=6倍和22 3-1=12 3倍。
c语言百钱买百鸡问题
百钱买百鸡问题——一百个铜钱买了一百只鸡,其中公鸡一只5钱、母鸡一只3钱,小鸡一钱3只,问一百只鸡中公鸡、母鸡、小鸡各多少)。
这是一个古典数学问题,设一百只鸡中公鸡、母鸡、小鸡分别为x ,y ,z ,问题化为三元一次方程组:⎩⎨⎧=++=++)(100)(1003/35百鸡百钱z y x z y x 这里x,y,z 为正整数,且z 是3的倍数;由于鸡和钱的总数都是100,可以确定x,y,z 的取值范围:1) x 的取值范围为1~20 2) y 的取值范围为1~333) z 的取值范围为3~99,步长为3 对于这个问题我们可以用穷举的方法,遍历x,y,z 的所有可能组合,最后得到问题的解。
数据要求问题中的常量: 无问题的输入: 无问题的输出:int x ,y ,z /*公鸡、母鸡、小鸡的只数*/ 初始算法1.初始化为1;2.计算x 循环,找到公鸡的只数; 3.计算y 循环,找到母鸡的只数; 4.计算z 循环,找到小鸡的只数; 5.结束,程序输出结果后退出。
算法细化算法的步骤1实际上是分散在程序之中的,由于用的是for 循环,很方便的初始条件放到了表达式之中了。
步骤2和3是按照步长1去寻找公鸡和母鸡的个数。
步骤4的细化 4.1 z =14.2 是否满足百钱,百鸡4.2.1 满足,输出最终百钱买到的百鸡的结果 4.2.2 不满足,不做处理 4.3 变量增加,这里注意步长为3 流程图图5-8 程序执行流程图程序代码如下#include "stdio.h"main(){int x,y,z;for(x=1;x<=20;x++)for(y=1;y<=33;y++)for(z=3;z<=99;z+=3){if((5*x+3*y+z/3==100)&&(x+y+z==100))/*是否满足百钱和百鸡的条件*/printf("cock=%d,hen=%d,chicken=%d\n",x,y,z);}}分析程序运行结果如下:cock=4,hen=8,chicken=78cock=8,hen=11,chicken=81cock=12,hen=4,chicken=84对于这个问题实际上可以不用三重循环,而是用二重循环,因为公鸡和母鸡数确定后,小鸡数就定了,即y100z 。
算法经典问题系列1百钱买百鸡问题
算法经典问题系列1 百钱买百鸡问题一说起唐朝,人们就会情不自禁地想起诗歌,绝对没有人会提到数学在数学上,虽说唐代并没有产生与其前的魏晋南北朝或其后的宋元相媲美的大师,却在数学教育制度的确立和数学典籍的整理方面有所建树.长达近三百年的唐代在数学方面最有意义的事情莫过于《算经十书》的整理和出版,这是高宗李治下令编撰的。
除了《周牌算经》《九章算术》《海岛算经》和《缀术》以外,《算经十书》中至少还有三部值得一提,分别是《孙子算经》《张丘建算经》和《缉古算经》'这三部书的共同特点是,每一部都提出了一个非常有价值的问题,并以此传世。
《张丘建算经》成书于公元5世纪,作者是北魏人.书中最后一道题堪称亮点,通常也被称为"百钱买百鸡"问题,民间则流传着县令考问神童的佳话书中原文如下:今有鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买鸡百只,问鸡翁、母、雏各几何?题目的意思是,公鸡5文钱1只,母鸡3文钱1只,小鸡1文钱买3只,现在用100文钱共买了100只鸡,问:在这100只鸡中,公鸡、母鸡和小鸡各是多少只?(设每种至少一只)算法分析:此题很显然是用枚举法,我们以三种鸡的个数为枚举对象(分别设为x,y,z),以三种鸡的总数(x+y+z)和买鸡用去的钱的总数(x*3+y*2+z)为判定条件,穷举各种鸡的个数。
枚举法,常常称之为穷举法,是指从可能的集合中一一枚举各个元素,用题目给定的约束条件判定哪些是无用的,哪些是有用的。
能使命题成立者,即为问题的解。
1.采用枚举算法解题的基本思路:2.确定枚举对象、枚举范围和判定条件;3.一一枚举可能的解,验证是否是问题的解下面是解这个百鸡问题的程序var x,y,z:integer;begin for x:=1 to 100 do for y:=1 to 100 do for z:=1 to 100 do if(x+y+z=100)and(x*5+y*3+z/3=100)then writeln('x=',x,'y=',y,'z=',z);{验证可能的解,并输出符合题目要求的解}end.这个算法学生容易想到,而重复是计算机的拿手好戏,算法可读性好。
百钱买百鸡问题
算法经典问题系列1 百钱买百鸡问题
一说起唐朝 人们就会情不自禁地想起诗歌 绝对没有人会提到数学在数
学上 虽说唐代并没有产生与其前的魏晋南北朝或其后的宋元相媲美的大师 却在数学教育制度的确立和数学典籍的整理方面有所建树.长达近三百年的唐代在数学方面最有意义的事情莫过于《算经十书》的整理和出版 这是高宗李治下令编撰的。
除了《周牌算经》《九章算术》《海岛算经》和《缀术》以外 《算经十书》中至少还有三部值得一提 分别是《孙子算经》《张丘建算经》和《缉古算经》'这三部书的共同特点是 每一部都提出了一个非常有价值的问题 并以此传世。
《张丘建算经》成书于公元5世纪 作者是北魏人.书中最后一道题堪称亮
点 通常也被称为"百钱买百鸡"问题 民间则流传着县令考问神童的佳话书中原文如下
今有鸡翁一 值钱五 鸡母一 值钱三 鸡雏三 值钱一 百钱买鸡百只
问鸡翁、母、雏各几何?
题目的意思是 公鸡5文钱1只 母鸡3文钱1只 小鸡1文钱买3只
现在用100文钱共买了100只鸡 问 在这100只鸡中 公鸡、母鸡和小鸡各是多少只?(设每种至少一只)算法分析
此题很显然是用枚举法 我们以三种鸡的个数为枚举对象(分别设为
x,y,z),以三种鸡的总数(x+y+z)和买鸡用去的钱的总数(x*3+y*2+z)为判定条件 穷举各种鸡的个数。
枚举法 常常称之为穷举法 是指从可能的集合中一一枚举各个元素 用
题目给定的约束条件判定哪些是无用的 哪些是有用的。
能使命题成立者 即为问题的解。
1.采用枚举算法解题的基本思路
2.确定枚举对象、枚举范围和判定条件。
C语言算法百钱买百鸡
int x, y ,z; //定义三个数进行循环
for (x=0; x<=100; x++)
{
for (y=0; y<=100; y++)
{
for (z=0; z<=100; z++)
{
if ((x+y+z==100)&&(5*x+3*y+z/3==100)&&(z%3==0)) //满足上面的条件时,就得出相应的结果
/*
程序演示:
百钱买百鸡的的问题:
鸡公一个,值钱五,鸡母值钱三,小鸡值钱一,百钱买百鸡,问公鸡,母鸡,小鸡各是几个
分析:
方程式如下:
a+b+c=100(百鸡)
5a+3b+c/3=100(百钱)
c%3=0
*/
/*
#include "stdio.h"
void main()
*/
#include "stdio.h"
void main()
{
int x, y, z;
for (x=0; x<=20; x++)
{
for (y=0; y<=33; y++)
{
z=100-x-y;
if ((5*x+3*y+z/3==100) && (z%3==%d,y=%d,z=%d\n",x, y, z);
}
}
}
}
}
数学故事-百鸡术
百鸡术中国古代解一次不定方程的一种方法。
南北朝时的数学著作《张丘建算经》(约成书于5世纪,后收入《算经十书》)卷下最末一题为:“今有鸡翁一直钱五,鸡母一直钱三,鸡雏三直钱一。
凡百钱买鸡百只。
问鸡翁母雏各几何”。
史称“百鸡问题”。
设为x表鸡翁数,y表鸡母数,z表鸡雏数,依题意可得:x + y + z = 100,5x + 3y + 1/3z = 100,这是一个一次不定方程组。
关于这一问题的解法,原书仅有“鸡翁每增四,鸡母每减七,鸡雏每益三”的简单术文,并列出全部正整数答案(4,18,78)、(8,11,81)和(12,4,84),至于“增四”、“减七”、“益三”的根据则没有叙述。
传本《张丘建算经》附有北宋谢察微的术草,其方法纯属于偶然。
北周甄鸾在《数术记遗》的注文中列举两道百鸡问题及各一组解,作为“计算”(即心算)的实例,对其算理则未深究。
南宋杨辉在《续古摘奇算法》(1275)中提到两种解法,他声称一种出于《辩古根源》、一种出于另一佚名写本(二书均已失传);第二种解法乃先固定某一未知数,由此将百鸡问题化为“鸡兔同笼问题”,相当于求解二元一次方程组。
清代学者研究百鸡问题的很多,其中较突出的是骆腾凤、丁取忠和时曰醇。
骆腾凤在《艺游录》(1815)中提出了一个十分巧妙的解法:先由题设方程组消去z,得7x + 4y = 100,两边同除以7,又得4y 恒等2 (mod7);另一方面,因有4y 恒等0 (mod4),于是得一“今有物不知数(4y),以七除之,余二;以四除之,恰尽”的问题,可由“大衍求一术”(见孙子剩余定理)解决。
丁取忠《数学拾遗》(1851)的解法与杨辉所记第二法类似,只是他先假定鸡翁无,求得鸡母数25,鸡雏数75;再由3y + 1/3z分析,若z加3,y减3,则鸡数不会变,而钱数则少8;又因为鸡翁的单价比鸡母的单价多2元,可以设想再将4只鸡母换成4只鸡翁,那么总的鸡数钱数都不变,这样就解释了“增四”、“减七”、“益三”的道理,并得出第一组解(4,18,78)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学号:0121210680225《算法设计与分析B》大作业题目多种解法求百钱百鸡问题学院计算机科学与技术学院专业软件工程班级Sy1201姓名李安福指导教师何九周2014 年12 月26 日多种解法求百钱百鸡问题摘要:中国古代数学家张丘建提出的“百钱买百鸡”可以采用蛮力法来解决。
本文给出了百钱百鸡问题的描述,采用蛮力法来解决这个问题,并通过分析对算法进行了优化,进一步提高了解决此问题的效率。
关键字:枚举,执行效率,蛮力法,不定方程,循环变量。
1引言蛮力法是一种简单直接地解决问题的方法,通常直接基于问题的描述和所涉及的概念定义。
这种方法经过很少的思考,把问题的所有情况或所有的过程交给计算机去一一尝试,从中找出问题的解。
由于计算机运算速度快,在解决问题时可采用这种“懒惰”的策略。
蛮力法的主要优点在于它是有广泛的适用性和简单性;它的缺点是大多数蛮力算法的效率都不高。
2问题概述 百钱百鸡问题:中国古代数学家张丘建在他的《算经》中提出了著名的“百钱买百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何?3问题的分析题目分析与算法设计这是一个古典数学问题我们假设公鸡、母鸡和小鸡的个数分别为x,y,z,那么买公鸡的钱数为5x ,买母鸡的钱数为3y ,买小鸡的钱数为z/3;再由题意,x,y 和z 的和为100,问题化为可三元一次方程组,该问题的数学模型如下:⎩⎨⎧=++=++)(100)(1003/35百鸡百钱z y x z y x这里x,y,z 为正整数,且z 是3的倍数;由于鸡和钱的总数都是100,可以确定x,y,z 的取值范围:1) x 的取值范围为1~20 2) y 的取值范围为1~33 3) z 的取值范围为1~99对于这个问题我们可以用穷举的方法,遍历x,y,z 的所有可能组合,最后得到问题的解。
4算法设计 4.1算法设计14.1.1数据要求问题中的常量: 无无问题的输出:int x,y,z /*公鸡、母鸡、小鸡的只数*/4.1.2初始算法1.初始化为1(循环语句中初始值为1);2.计算x循环,找到公鸡的只数;3.计算y循环,找到母鸡的只数;4.计算z循环,找到小鸡的只数;5.结束,程序输出结果后退出。
4.1.3算法细化算法的步骤1实际上是分散在程序之中的,由于用的是for循环,很方便的初始条件放到了表达式之中了。
这三个步骤按照步长1去寻找公鸡和母鸡的个数。
步骤2的细化1.z=12.是否满足百钱,百鸡3. 满足,输出最终百钱买到的百鸡的结果4.不满足,不做处理4.1.4流程图算法设计1程序代码如下:#include "stdio.h"main(){int x,y,z;for(x=1;x<=20;x++)for(y=1;y<=33;y++)for(z=1;z<=99;z++){if((5*x+3*y+z/3==100)&&(x+y+z==100)&&z%3==0)/*是否满足百钱和百鸡的条件*/ printf("cock=%d,hen=%d,chicken=%d\n",x,y,z);}}程序运行结果如下:cock=4,hen=8,chicken=78cock=8,hen=11,chicken=81cock=12,hen=4,chicken=84算法设计1程序运行截图如下:算法分析1:对于这个问题我们可以计算一下她的枚举尝试20*33*99*=65340次。
可见算法的效率很低。
4.2算法设计2对算法1的改进:那么我们可不可以进行一定的改进呢?当我们分析题目要求时可以发现,“买小鸡的钱数为z/3”这一句中我们可以分析得到这么一个信息买小鸡的钱应该为整数,那么小鸡的数量z则应该是3的倍数,所以为了减少枚举效率,我们可以把对z的for循环语句中的步长设为3,这样可以减少很多的循环次数。
从而对算法进行一次改进,得到算法设计2.算法设计2的程序如下:main() {int x,y,z;for(x=1;x<=20;x++) for(y=1;y<=33;y++)for(z=3;z<=99;z+=3) /*注意此时的步长变为了3,从而减少了循环次数*/ {if((5*x+3*y+z/3==100)&&(x+y+z==100)&&(z%3==0))/*是否满足百钱和百鸡的条件*/printf("cock=%d,hen=%d,chicken=%d\n",x,y,z); } }程序运行结果如下: cock=4,hen=8,chicken=78 cock=8,hen=11,chicken=81 cock=12,hen=4,chicken=84算法设计2程序运行截图如下:算法分析2:此时我们再来计算一下以上算法需要的枚举尝试为20*33*99=21780次。
可见此时算法的效率有了一定的提高,枚举尝试变为了第一次所做程序的枚举尝试的三分之一。
4.3算法设计3对算法2的改进:可是改进 一次后的算法就是最理想的吗?我们可否再进行改进?答案是肯定的。
其实我们再仔细分析一下可以发现,对于这个问题实际上可以不用三重循环,而是用二重循环,因为公鸡(x )和母鸡(y)数确定后,小鸡数(z)就确定了,即y -x -100z 。
从而就无需再进行枚举了,此时的约束条件只有一个:5*x+3*y+z/3==100。
从而对以上算法进行改进。
算法设计3的程序如下:#include "stdio.h" main() {for(x=1;x<=20;x++)for(y=1;y<=33;y++){z=100-x-y ;/*通过x,y获得z,此时少了一层循环*/if((5*x+3*y+z/3==100)&&z%3==0)/*是否满足百钱和百鸡的条件*/printf("cock=%d,hen=%d,chicken=%d\n",x,y,z);}}程序运行结果如下:cock=4,hen=8,chicken=78cock=8,hen=11,chicken=81cock=12,hen=4,chicken=84算法设计3程序运行截图如下:算法设计3的分析:以上算法只需要的枚举尝试为20*33=660次。
实现时约束条件又限定z能被3整除时,才会判断5*x+3*y+z/3=100。
这样便省去了z不被3整除是的算法计算和条件判断,相比前两种算法又进一步提高了算法的效率。
算法设计3的进一步分析:可是这次是不是最好的算法呢?有人可能会问,既然确定公鸡(x)的数量和母鸡(y)的数量后,就可以确定小鸡(z)的数量;那么我们可不可以先确定公鸡(x)的数量和小鸡(z)的数量或先确定母鸡(y)和小鸡(z)的数量呢。
下面我们对这几种情况的算法效率进行分析:情况一:当确定公鸡(x)的数量和母鸡(y)的数量后,由于限制条件(百鸡:x+y+z=100)我们可得母鸡的数量为z=100-x-y;此时循环语句就该改为for(x=1;x<=20;x++)和for(y=1;y<=33;y++),因此我们可以发现程序的枚举效率为20*33=660。
情况二:当确定公鸡(x)的数量和小鸡(z)的数量后,由于限制条件(百鸡:x+y+z=100)我们可得母鸡的数量为y=100-x-z;此时循环语句就该改为for(x=1;x<=20;x++)和for(z=3;z<=99;z+=3),因此我们可以发现程序的枚举效率为20*33=660。
情况三:得公鸡的数量为x=100-y-z;此时循环语句就该改为for(y=1;y<=33;y++)和for(z=3;z<=99;z+=3),因此我们可以发现程序的枚举效率为33*33=1089。
结论:根据对几种情况的对比分析可以发现,情况一和情况二枚举效率都为660,而情况三的效率为1089,所以选择情况一和情况二是较为合理的。
当然这三种情况的效率都优于使用三重循环时的算法。
5结束语在本文中给出了应用蛮力法的一个实例,即百钱百鸡问题,在解决百钱百鸡这个实际问题时我们利用到了蛮力法策略中的枚举法,通过对此问题的分析我们的出了相应的算法。
并在得出最佳的算法前我们对初次所得算法进行了两次的改进,通过对每一次所得算法的枚举尝试计算,第一次的改进把枚举尝试减少到原来的三分之一,第二次的改进通过减少了一次的for循环,从而又一次的大大减少了枚举尝试。
经过多次的算法改进后我们得到了我们最理想的算法。
通过解决这一问题我们可以看出,同一问题可以有不同的枚举范围、不同的枚举对象,解决问题的效率差别会很大。
当然,在我们解决每一个实际问题时,有时并不是得出了答案即可,我们应该尽可能的寻找最优解,要不断地对方法进行改进,对算法的一点小小的改进可能会减少很多计算机的负担。
参考文献[1] 吕国英.算法设计与分析[M].北京:清华大学出版,2009:154-165.[2] 谭浩强.c程序设计教程.北京清华大学,2004.6:IV.TP312.[3] 耿国华.算法设计与分析.高等教育出版社,2012.[4] 屈婉玲.算法设计与分析.北京清华大学出版社,2011.大作业成绩评定表教师签名:。