百马百担问题。有100匹马,驮100担货,大马驮3担,中马驮2担,两匹小马1担,编程计算所有可能的驮法?
标签:style blog io color sp for on div 问题
百马百担问题。有100匹马,驮100担货,大马驮3担,中马驮2担,两匹小马1担,编程计算所有可能的驮法?
无
输出所有可能的驮法。
每行输出一种驮法,每种驮法依次输出:
大马数,中马数,小马数
如2,30,68
表示大马数为2,中马数为30,小马数为68
下面的初学者容易写出的代码,而且最常犯错的地方就是忘记 z % 2 == 0
1 #include <stdio.h> 2 3 int main(void) 4 { 5 int x, y, z; 6 for(x = 0; x <= 33; x++) 7 for(y = 0; y <= 50; y++) 8 for(z = 0; z <= 100; z++) { 9 if(x + y + z == 100 && 3 * x + 2 * y + z / 2 == 100 && z % 2 == 0) 10 printf("%d,%d,%d\n", x, y, z); 11 } 12 13 return 0; 14 }
能不能去掉z % 2 == 0这个条件呢? 一种思路就是将 3 * x + 2 * y + z / 2 == 100两边都乘以2,等式成为6*x+4*y+z==200。 更好的做法是修改循环变量的步长
1 #include <stdio.h> 2 3 int main(void) 4 { 5 int x, y, z; 6 for(x = 0; x <= 33; x++) 7 for(y = 0; y <= 50; y++) 8 for(z = 0; z <= 100; z += 2) { 9 if(x + y + z == 100 && 3 * x + 2 * y + z / 2 == 100) 10 printf("%d,%d,%d\n", x, y, z); 11 } 12 13 return 0; 14 }
如果进一步观察,发现第8行的枚举z是没有必要的,因为z必然是100-x-y,这样会节省不少开销。
1 #include <stdio.h> 2 3 int main(void) 4 { 5 int x, y, z; 6 for(x = 0; x <= 33; x++) 7 for(y = 0; y <= 50; y++) { 8 z = 100 - x - y; 9 if(z % 2 == 0 && 3 * x + 2 * y + z / 2 == 100) 10 printf("%d,%d,%d\n", x, y, z); 11 } 12 13 return 0; 14 }
变化一下判断条件,可以用100-x-y代替z,从而抹去z的痕迹。 6x+4y+z = 100+5x+3y,有下面第8行的判等式(该式实际一开始就可以推出),这个式子是推导的结果,绝非一眼所能看出。
1 #include <stdio.h> 2 3 int main(void) 4 { 5 int x, y; 6 for(x = 0; x <= 33; x++) 7 for(y = 0; y <= 50; y++) { 8 if(5 * x + 3 * y == 100) 9 printf("%d,%d,%d\n", x, y, 100 - x - y); 10 } 11 12 return 0; 13 }
有了第8行,可看出x不超过20,而且y也不必枚举了。程序只剩一层循环,得到了极大的优化。
1 #include <stdio.h> 2 3 int main(void) 4 { 5 int x, y; 6 for(x = 0; x <= 20; x++){ 7 y = 100 - 5 * x; 8 if(y % 3 == 0){ 9 y /= 3; 10 printf("%d,%d,%d\n", x, y, 100 - x - y); 11 } 12 } 13 14 return 0; 15 }
在本例中,我们通过步步优化,从三层循环简化到一层循环,执行效率是提高了,但是代码的可读性却是大大下降了。对于小程序来讲,可读性更重要一些。但是在一些性能关键的地方,优化是必不可少的。
标签:style blog io color sp for on div 问题
原文地址:http://www.cnblogs.com/4bytes/p/4139011.html