甲、乙、丙三位鱼夫出海打鱼,他们随船带了21只箩筐。当晚返航时,他们发现有七筐装满了鱼,还有七筐装了半筐鱼,另外七筐则是空的,由于他们没有秤,只好通过目测认为七个满筐鱼的重量是相等的,7个半筐鱼的重量是相等的。在不将鱼倒出来的前提下,怎样将鱼和筐平分为三份?
*问题分析与算法设计
根据题意可以知道:每个人应分得七个箩筐,其中有3.5筐鱼。采用一个3*3的数组a来表示三个人分到的东西。其中每个人对应数组a的一行,数组的第0列放分到的鱼的整筐数,数组的第1列放分到的半筐数,数组的第2列放分到的空筐数。由题目可以推出:
。数组的每行或每列的元素之和都为7;
。对数组的行来说,满筐数加半筐数=3.5,但为了便于进行关系运算,将其乘以2变成整数7;
。每个人所得的满筐数不能超过3筐;
。每个人都必须至少有1 个半筐,且半筐数一定为奇数
对于找到的某种分鱼方案,三个人谁拿哪一份都是相同的,为了避免出现重复的分配方案,可以规定:甲、乙、丙分到的满筐数依次减少,相应的,分到的半筐数依次增多
* 运行结果
It exists possible distribution plans:
No.1 Full basket Semi--basket Empty
fisher A: 3 1 3
fisher B: 2 3 2
fisher C: 2 3 2
No.2 Full basket Semi--basket Empty
fisher A: 3 1 3
fisher B: 3 1 3
fisher C: 1 5 1
*思考题
晏会上数学家出了一道难题:假定桌子上有三瓶啤酒,癣瓶子中的酒分给几个人喝,
但喝各瓶酒的人数是不一样的。不过其中有一个人喝了每一瓶中的酒,且加起来刚好是一瓶,
请问喝这三瓶酒的各有多少人?
(答案:喝三瓶酒的人数分别是2人、3人和6人)
*/
#include<stdio.h>
int main()
{
int a[3][3] = {0};//用来存储三个人分得的各种筐的数量,每行表示一个人,每列表示一种筐
int count = 0; //累计分配方案的数量
int f1, f2, f3, f4;//表示几个条件
for (a[0][0]=1; a[0][0]<=3; a[0][0]++)//试探甲分得的满筐a[0][0]的值,满筐数不能>3
{
for (a[1][0]=1; a[1][0]<=a[0][0]; a[1][0]++)//试探乙分得的满筐a[1][0]的值,不能比甲多
{
a[2][0] = 7 - a[0][0] - a[1][0];//丙分得的满筐数等于总数减去甲和乙的
for (a[2][1]=1; a[2][1]<=5; a[2][1]++)//试探丙分得的半筐a[2][1]的值,满筐数不能>5
{
for (a[1][1]=1; a[1][1]<=a[2][1]; a[1][1]++)//试探乙分得的半筐a[1][1]的值,不能比丙多
{
a[0][1] = 7 - a[1][1] - a[2][1];//甲分得的半筐数等于总数减去乙和丙的
//甲、乙、丙的空筐数等于总筐数减去满筐数和半筐数
a[0][2] = 7 - a[0][0] - a[0][1];
a[1][2] = 7 - a[1][0] - a[1][1];
a[2][2] = 7 - a[2][0] - a[2][1];
f1 = (a[0][2]+a[1][2]+a[2][2] == 7);//三个人的空筐数加起来等于7个
//甲、乙、丙得到的鱼等于3.5筐,为了便于比较,以半筐为一个单位,共7个单位
f2 = (a[0][0]*2 + a[0][1] == 7);
f3 = (a[1][0]*2 + a[1][1] == 7);
f4 = (a[2][0]*2 + a[2][1] == 7);
if (f1 && f2 && f3 && f4)//输出满足条件的组合
{
printf("\nNo.%d \t Full\tSemi\tEmpty\n", ++count);
int n;
for (n=0; n<3; n++)
printf("fisher %c: %d \t%d\t%d\n",'A'+n,a[n][0],a[n][1],a[n][2]);
}
}
}
}
}
getchar();
return 0;
}
评论