首页 > 代码库 > 鸡兔同笼问题、百鸡问题、辗转相除法求最大公约数
鸡兔同笼问题、百鸡问题、辗转相除法求最大公约数
一、鸡兔同笼
鸡和兔子35只,腿一共有94条,求出鸡和兔子的数量各是多少?(鸡的数目是23,兔子的数目是12)
$n = 0;
for($ i=1;$i<35;$i++){
$n ++; //n=34;
$ j=35-i;
if(i*2+j*4==94){
printf("鸡的数目是%d只, 兔子的数目是%d只",$i,$j);
}
}
此时,循环进行了34次。但是,有些循环是无意义的,因为得到了结果,循环还在继续往下执行。我们知道:两个未知数,两个方程,其方程组的解唯一!那么我们可以让流程控制的if语句在得到结果以后,终止循环!
改进如下:
$n = 0;
for($ i=1;$i<35;$i++){
$n ++; //n=22;
$ j=35-i;
if(i*2+j*4==94){
printf("鸡的数目是%d只, 兔子的数目是%d只",$i,$j);
break;
}
}
此时,循环只需要进行22次即可。再有,在确定循环变量的时候,分析:兔有四条腿,而鸡只有两只脚,兔子数明显比鸡的个数所得到的腿数更有效!(有点绕,大家不理解的看下面代码~)
终极版改进如下:
$n = 0;
for($ i=1;$i<35;$i++){
$n ++; //n=11;
$ j=35-i;
if(i*4+j*2==94){
printf("鸡的数目是%d只, 兔子的数目是%d只",$j,$i);
break;
}
}
最后,我们获得结果只需要循环11次!比起最开始的34次,节省了23次不必要的循环!可能大家觉得没什么,如果是循环一万次一百万次呢,不必要的循环多了,消耗的资源也就多了,获得最终结果的速度也慢了。
二、百鸡问题
张丘建在《算经》中提出了“百鸡问题”:鸡公一值钱五,鸡母一值钱三,鸡雏三值钱一,百钱买百鸡,问鸡公、母、雏各几何?
先给大家罗列出结果:
公鸡有0只,母鸡有25只,小鸡有75只
公鸡有4只,母鸡有18只,小鸡有78只
公鸡有8只,母鸡有11只,小鸡有81只
公鸡有12只,母鸡有4只,小鸡有84只
同样的,我们让计算机帮我们计算,代码如下:
$n = 0;
for($cocks = 0;$cocks <= 20;$cocks ++){
for($hens = 0;$hens <= 33;$hens ++){
$n++; //n = 714;
$chicks = 100 - $cocks - $hens;
if(5*$cocks + 3*$hens + $chicks/3 == 100) {
printf("公鸡有%d只,母鸡有%d只,小鸡有%d只<br />",$cocks,$hens,$chicks);
}
}
}
要想得到结果,计算机需要循环21*34=714次。接下来怎么优化呢?假设公鸡数为x,母鸡数为y,小鸡数为z。我们先把z消去,得7x+4y = 100,x = (100-4y)/7,那么x最大只能得到14,节省了(20-14)*34=204次循环!另外,我们可以发现,如果少买7只母鸡,就可多买4只公鸡和3只小鸡!我们是不是可以再得到最大的母鸡数,然后递减7,以及公鸡数+4、小鸡数+3来获取最终结果呢?
代码如下:
$n = 0;
for($cocks = 0;$cocks <= 14;$cocks ++){
for($hens = 33;$hens >=0;$hens --){
$n++;
$chicks = 100 - $cocks - $hens;
if(5*$cocks + 3*$hens + $chicks/3 == 100) {
printf("公鸡有%d只,母鸡有%d只,小鸡有%d只<br />",$cocks,$hens,$chicks);
break; //得到最大的母鸡数;
}
}
if(printf()){
break; //如果printf()有返回值,即内层循环得出了结果,那么就终止!;
}
}
不知道为什么浏览器报错了。。。程序出现问题,待改进。
三、辗转相除法求最大公约数
$num1 = $_GET[‘n1‘];
$num2 = $_GET[‘n2‘];
$num = $num1;
$div = $num2;
// 3, 求余数,开始循环体
do {
$mod = $num % $div;
// 刚才的除数就变成了被除数
$num = $div;
// 刚才的余数就变成了除数
$div = $mod;
}while($mod != 0);
echo "最大公约数为:",$num;
鸡兔同笼问题、百鸡问题、辗转相除法求最大公约数