本文共 4816 字,大约阅读时间需要 16 分钟。
小续
以下是我收集的一些有趣的计算实例,希望能够提高读者的编程水平及分析问题/解决问题的能力
---------------------------------------------
马克思手稿中的数学题
马克思手稿中有一道趣味数学题:有30个人,其中有男人、女人和小孩,在一家饭馆吃饭共花了50先令。若每个男人花3先令,每个女人花2先令,每个小孩花1先令。问男人、女人和小孩各有几人?
实例解析:
设x,y,z分别代表男人、女人和小孩的人数。按题目要求,可得到下面方程:
x + y + z = 30 (1)
3x + 2y + z = 50 (2)
(2)-(1)可得
2x + y = 20 (3)
由(3)式可知,x的变化范围是1~10 (根据题意,男人、女人、小孩都有,故x、y、z都不能为0)。
程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> int main() { int x,y,z,count = 0; clrscr(); puts ( " >> The solutions are:" ); printf ( " No. Men Women Children\n" ); printf ( "--------------------------------\n" ); for (x = 1; x <= 10; x++) { y = 20 - 2*x; //由(3)式求y z = 30 – x - y; //由(1)式求z if (3*x + 2*y + z == 50 && y && z) //当前组合是否满足式(2) printf ( " <%2d> | %2d | %2d | %2d\n" , ++count,x,y,z); } printf ( "--------------------------------\n" ); printf ( " Press any key to quit..." ); getch(); return 0; } |
配对新郎和新娘
3对情侣参加婚礼,3个新郎为A、B、C,3个新娘为X、Y、Z。有人不知道谁和谁结婚,于是询问了6位新人中的3位,但听到的回答是这样的:A说他将和X结婚;X说她的未婚夫是C;C说他将和Z结婚。这人听后知道他们在开玩笑,全是假话。请编程确认谁和谁是一对。
实例解析:
分表将A、B、C用1,2,3表示,将X和A结婚表示为“X == 1”,将Y不与A结婚表示为“Y !=1”,按题目叙述可写出下列表达式:
X != 1 A不与X结婚
X != 3 X的未婚夫不是C
Z != 3 C不与Z结婚
穷举满足以上条件所有可能的情况。
程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> int main() { int x,y,z; puts ( " >> The solutions are:" ); printf ( "-------------------------------------\n" ); for (x = 1; x <= 3; x++) //穷举x的全部可能配偶 for (y = 1; y <= 3; y++) //穷举y的全部可能配偶 for (z = 1; z <= 3; z++) //穷举z的全部可能配偶 if (x!=1 && x!=3 && z!=3 && x!=y && x!=z && y!=z) { printf ( "X will marry to %c.\n" , 'A' +x-1); printf ( "Y will marry to %c.\n" , 'A' +y-1); printf ( "Z will marry to %c.\n" , 'A' +z-1); } printf ( "--------------------------------------\n" ); printf ( " Press any key to quit..." ); getch(); return 0; } |
分糖果
10个小孩围成一圈分糖果,老师分给第一个小孩10块,第二个小孩2块,第三个小孩8块,第四个小孩22块,第五个小孩16块,第六个小孩4块,第七个小孩10块,第八个小孩6块,第九个小孩14块,第十个小孩20块。然后所有的小孩同时将手中的糖分一半给右边的小孩,糖块为奇数的可向老师再要一块。问这样的操作经过几次,大家手中的糖一样多?每人有多少块糖?
实例解析:
分糖过程是一个机械的重复过程。算法完全可以按照描述的过程进行模拟。
程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <stdio.h> void print( int s[]); int judge( int c[]); int j = 0; int main() { int sweet[10] = {10,2,8,22,16,4,10,6,14,20}; int i, t[10], k; printf ( "Child No. 1 2 3 4 5 6 7 8 9 10\n" ); printf ( "-------------------------------------\n" ); printf ( "Round No.|\n" ); print(sweet); //输出每个人手中糖的块数 while (judge(sweet)) { //若不满足要求则继续进行循环 for (i = 0; i < 10; i++) t[i] = sweet[i] = sweet[i]/2; //每个人手中的糖分成两半 for (k = 0; k < 9; k++) { sweet[k+1] = sweet[k+1] + t[k]; //分出的一半糖给右边 if (sweet[k+1]%2!=0) sweet[k+1]++; } sweet[0] += t[9]; if (sweet[0]%2!=0) sweet[0]++; print(sweet); //输出当前每个孩子中手中的糖数 } printf ( "-------------------------------------\n" ); printf ( "\n Press any key to quit..." ); getch(); return 0; } int judge( int c[]) { int i; for (i = 0; i < 10; i++) //判断每个孩子手中的糖是否相同 if (c[0] != c[i]) return 1; //不相同返回 1 return 0; } void print( int s[]) //输出数组中每个元素的值 { int k; printf ( " <%2d> | " , j++); for (k = 0; k < 10; k++) printf ( "%4d" , s[k]); printf ( "\n" ); } |
波瓦松的分酒问题
法国著名数学家波瓦松(Poison)在青年时代研究过一个有趣的数学问题:某人有12品脱的啤酒一瓶,想从中倒出6品脱,但他没有6品脱的容器,仅有一个8品脱和5品脱的容器,怎样才能将啤酒分成两个6品脱呢?
实例解析:
将12品脱酒用8品脱和5品脱的空瓶平分,可以抽象为解不定方程:
8x - 5y = 6
其意义是:从12品脱的瓶中向8品脱的瓶中倒x次,并且将5品脱瓶中的酒向12品脱的瓶中倒y次,最后在12品脱的瓶中剩余6品脱的酒。
分别用a,b,c代表12品脱、8品脱和5品脱的瓶子,求出不定方程的整数解,按照不定方程的意义则倒酒法为:
a→b→c→a
x y
倒酒的规则如下:
(1)按a→b→c→a的顺序;
(2) b倒空后才能从a中取;
(3) c装满后才能向a中倒。
程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include <stdio.h> void getti( int a, int y, int z); int i; //最后需要分出的重量 int main() { int a, y, z; printf ( ">>Input Full bottle a,Empty y,z, and Get volumes i:\n" ); //a第一个瓶的容量 y:第二个瓶的容量 z:第三个瓶的容量 printf ( " >> " ); scanf ( "%d%d%d%d" , &a, &y, &z, &i); getti(a, y, z); //按a -> y -> z -> a的操作步骤 printf ( "\n Press any key to quit..." ); getch(); return 0; } void getti( int a, int y, int z) //a:第一瓶的容量 y:第二个瓶的容量 z:第三个瓶的容量 { int b = 0, c = 0, j = 0; // b:第二瓶酒重 c:第三瓶酒重 j: 步数 puts ( " >> The division steps are as follows.\n" ); printf ( " Bottle: a<%d> b<%d> c<%d>\n" ,a,y,z); printf ( "-----------------------------\n" ); printf ( " Step No.|\n" ); printf ( " <%d> | %4d %4d %4d\n" ,j++,a,b,c); while (a!=i && b!=i && c!=i ) { //当三个瓶的酒都!=i if (!b) { //如果第二瓶为空,则从第一瓶倒入第二瓶 a -= y; b = y; } else if (c == z) { //如果第三瓶满,则将第三瓶倒入第一瓶中 a += z; c = 0; } else if (b > z-c) { //如果第二瓶的酒>第三瓶的剩余空间 b -= (z-c); //由第二瓶倒满第三瓶,第二瓶保留剩余部分 c = z; } else { //将第二瓶全部倒入第三瓶中 c += b; b = 0; } printf ( " <%d> | %4d %4d %4d\n" ,j++,a,b,c); } printf ( "-----------------------------\n" ); } |
本文转自infohacker 51CTO博客,原文链接:http://blog.51cto.com/liucw/1171360
转载地址:http://fgxyl.baihongyu.com/