临近考试,准备预习一下算法设计(orz),在百元买百鸡视频求解过程中,尝试了一下。
问题描述
公鸡每只五文钱,母鸡每只3文钱,三只小鸡1文钱。现用100文钱买100只鸡。问这100只鸡中有多少只公鸡,多少只母鸡,多少只小鸡?
三重循环求解
设公鸡为x只,母鸡为y只,小鸡为z只。
int x,y,z;
for(x = 1; x <= 100; x++) {
for(y = 1; y <= 100; y++) {
for(z = 1; z <= 100; z++) {
if((x+y+z == 100) && (x*5 + y*3 + z/3 == 100) && (z%3 == 0))
System.out.println("公鸡"+x+"只,母鸡"+y+"只,小鸡"+z+"只");
}
}
}
输出结果为:
但是这种算法需要进行1003次if判断,我们可以简化一下得出双重循环求解。
双重循环求解
因为只有100文钱,所以我们可以计算出每种鸡的取值范围:
5x<=100,得出x<=20;
3y<=100,得出y<=33;
小鸡数则为z=100-x-y
int x,y,z;
for(x=1; x<=20; x++) {
for(y =1; y <=33;y++) {
z =100 -x -y;
if((z%3 == 0)&&(x*5+y*3+z/3 == 100))
System.out.println("公鸡"+x+"只,母鸡"+y+"只,小鸡"+z+"只");
}
}
输出结果:
这种算法需要进行20*33=660次if语句判断,虽然是简化了一些,但是我们还可以继续优化即一重循环。
一重循环求解
首先由题意我们可以得出一个不定方程组:
x+y+z = 100 (1)
5x+3y+z/3 = 100 (2)
令(2)*3-(1)得:
14x+8y = 200
可得 y = 25-(7/4)x
再次化简算法:
int x,y,z;
for(x=1;x<=20;x++) {
y = 25-x*7/4;
z= 100 - x - y;
if((z%3 == 0)&&(x*5+y*3+z/3 == 100))
System.out.println("公鸡"+x+"只,母鸡"+y+"只,小鸡"+z+"只");
}
解释一下为什么需要改动:原式*y=25-(7/4)x;这里7/4在系统中是取的商而非我们通常计算的小数:
可以看到这样计算的结果误差是非常大的,所以需要改为y = 25-7*x/4;但是又会产生一个新的问题:
所以我们应该增加一个判断条件,即y>0;
int x,y,z;
for(x=1;x<=20;x++) {
y = 25-x*7/4;
z= 100 - x - y;
if((z%3 == 0)&&(x*5+y*3+z/3 == 100) && (y > 0))
System.out.println("公鸡"+x+"只,母鸡"+y+"只,小鸡"+z+"只");
}
这时的输出结果为: