张丘建的百钱百鸡问题
为了准备9月25号高德公司的笔试,我在网上搜高德笔试相关的资料时看到这样《算经》中的一道题:
一只公鸡5文钱,一只母鸡3文钱,三只小鸡1文钱。问,一百文钱买100只鸡,公鸡、母鸡和小鸡各是多少只?
解题分析:
设公鸡、母鸡和小鸡分别为x,y,z只;那么,可以列出方程
x + y + z = 100;------ 1
5x + 3y + z/3 = 100;-----2
于是,变成接不定方程的整数解集;
如果一百文钱全部买公鸡,能买20只,即 0 < x < 20;全买母鸡,能买33只,即 0 < y < 33;
所以,可以这么来实现:
1 public class TestZQJ { 2 public static void main(String[] args) { 3 int x, y, z; 4 int count = 0; 5 for(x=0;x<=20;x++) { 6 for(y=0;y<=33;y++) { 7 z = 100 - x - y; 8 if(z%3 == 0 && z/3+3*y+5*x == 100 && x+y+z == 100) { 9 count++; 10 System.out.println("case "+count+": 公鸡"+x+": 母鸡"+y+": 小鸡"+z); 11 } 12 } 13 } 14 } 15 }
结果:
但是这个方式实现的时间复杂度为O(N2),看了相关的文章,发现可以这样来优化代码。
算法分析:
还是这两个方程
x + y + z = 100;------ 1
5x + 3y + z/3 = 100;-----2
2式*3 - 1式,得:
7x + 4y = 100
所以,y = 25 - (7/4)x;
又因为y是整数,而且0 < y < 100,所以,可以令
x = 4k;
所以y = 25 - 7k,即 0 < 25 - 7k < 100,解出,
0 <= k < 4,即k取0,1,2,3
于是程序可以如此实现:
public class TestZQJ { public static void main(String[] args) { int x=0,y=0,z=0; for(int k=0;k < 4;k++) { x = 4*k; y = 25 - 7*k; z = 75 + 3*k; System.out.println("case " + k + ":公鸡" + x+ ":母鸡" + y + ":小鸡" + z); } } }
结果与上述结果一致。
人生的智慧,在于确认自己是自由的存在着,而非宿命的被命运所规定.