一个经理有三个女儿,三个女儿的年龄加起来等于13,三个女儿的年龄乘起来等于经理自己的年龄,有一个下属已知道经理的年龄,但仍不能确定经理三个女儿的年龄,这时经理说只有一个女儿的头发是黑的,然后这个下属就知道了经理三个女儿的年龄。请问三个女儿的年龄分别是多少?为什么?
解答:
看似简单的题目做起来却让我费了不少脑子,真叫它“只有一个女儿的头发是黑的”这个条件给忽悠住了……呵呵~~~知道了正确答案后(真是羡慕网上达人们的智慧啊)才发现,哎~,这句话既是解决问题的关键,也是糊弄我们的陷阱。。。先来看看正确的解题思路吧。
首先,设三个女儿的年龄分别为x,y,z,经理的年龄为A,且x≥y≥z。(此处先不考虑“只有一个女儿的头发是黑的”这一条件,为什么一会解释)
则根据已知得:
x+y+z=13 ………………………………①
(三个女儿的年龄加起来等于13)
xyz=A<60 ………………………………②
(三个女儿的年龄乘起来等于经理的年龄,经理在职年龄应小于60岁)
xyz-x>22 ………………………………③
(经理有第一个女儿时应超过法定年龄)
解式2,z^3<xyz<60
则 z≤3
根据式1列表:
z | y | x | A | xyz-x |
1 | 1 | 11 | 11 | 0 |
1 | 2 | 10 | 20 | 10 |
1 | 3 | 9 | 27 | 18 |
1 | 4 | 8 | 32 | 24 |
1 | 5 | 7 | 35 | 28 |
1 | 6 | 6 | 36 | 30 |
2 | 2 | 9 | 36 | 27 |
2 | 3 | 8 | 48 | 40 |
2 | 4 | 7 | 56 | 49 |
2 | 5 | 6 | 60 | 54 |
3 | 3 | 7 | 63 | 56 |
3 | 4 | 6 | 72 | 66 |
3 | 5 | 5 | 75 | 70 |
表中满足式2、3条件的解如下:
z | y | x | A | xyz-x |
1 | 4 | 8 | 32 | 24 |
1 | 5 | 7 | 35 | 28 |
1 | 6 | 6 | 36 | 30 |
2 | 2 | 9 | 36 | 27 |
2 | 3 | 8 | 48 | 40 |
2 | 4 | 7 | 56 | 49 |
2 | 5 | 6 | 60 | 54 |
此时追加条件1:“有一个下属已知道经理的年龄,但仍不能确定经理三个女儿的年龄”
假设此时我们知道了经理的年龄,比如是35,那么他女儿的年龄肯定就确定了,为(1,5,7)。但是题设说下属知道了经理的年龄还不知道其女儿的年龄,这说明满足条件的解一定有两个以上,而表中只有36这一组数据具有两个不同的解(1,6,6)(2,2,9),所以范围确定至此。
再追加条件2:“只有一个女儿的头发是黑的”
也就是说,x>y≥z,所以答案就很清楚了,为(2,2,9)。
反过来看,此题目实际上分为两个部分——已知条件部分和追加判断部分。“只有一个女儿的头发是黑的”是追加的判断条件,没有作对的问题就出在把追加的判断条件作为了已知条件来处理了。
像我一样,大部分的人在开始时总会把“只有一个女儿的头发是黑的”作为已知,得出x>y≥z的结论,并用其进行求解。这个结论是没错,但是逻辑顺序却错了,我们来看:
设三个女儿的年龄分别为x,y,z,经理的年龄为A,但x>y≥z(此处考虑了“只有一个女儿的头发是黑的”这一条件)
同理,根据式2得z≤3
根据式1列表为:
z | y | x | A | xyz-x |
1 | 1 | 11 | 11 | 0 |
1 | 2 | 10 | 20 | 10 |
1 | 3 | 9 | 27 | 18 |
1 | 4 | 8 | 32 | 24 |
1 | 5 | 7 | 35 | 28 |
2 | 2 | 9 | 36 | 27 |
2 | 3 | 8 | 48 | 40 |
2 | 4 | 7 | 56 | 49 |
2 | 5 | 6 | 60 | 54 |
3 | 3 | 7 | 63 | 56 |
3 | 4 | 6 | 72 | 66 |
则上表中满足式2、3条件的解如下:
z | y | x | A | xyz-x |
1 | 4 | 8 | 32 | 24 |
1 | 5 | 7 | 35 | 28 |
2 | 2 | 9 | 36 | 27 |
2 | 3 | 8 | 48 | 40 |
2 | 4 | 7 | 56 | 49 |
2 | 5 | 6 | 60 | 54 |
比较前面发现:(1,6,6)这组数据没了。。。这上哪解去啊,这个时候有人就想了,孩子多少岁长头发来?1岁?2岁?3岁?呵呵,实际上已经差之毫厘,谬以千里了。。。
附上代码:
//已知条件是:假设三个女儿的年龄分别为x,y,z,经理年龄为A,则x+y+z=13,x*y*z=A<60,z<=3,x>=y>=z;追加条件是x>y>=z(只有一个女儿的头发是黑的)
#include <iostream>
#include <vector>
#include <map>
using namespace std;
struct DaughterAge //三个女儿的年龄的组合
{
int x;
int y;
int z;
};
int main()
{
vector<DaughterAge>vecDaughterAge; //三个女儿年龄的可能值组合的集合
map<int,int>mManagerAgeAndCounts; //根据vecDaughterAge得到对应的该经理的年龄和次数的集合
vector<DaughterAge>::iterator vIter;
map<int,int>::iterator mIter;
int x,y,z; //三个女儿的年龄
int a; //经理的年龄
DaughterAge tmp; //临时变量,临时存储数据
//枚举所有可能的情况
for(z=1; z<=3; ++z)
{
for(y=1; y<13-z; ++y)
{
x=13-z-y; //根据y和z值求出x
a=x*y*z; //求出对应的a
if((a <60) && (a-x >22) && (x>=y && y>=z)) //判断这组数据是否符合已知条件
{
tmp.x=x;
tmp.y=y;
tmp.z=z;
//判断a值是否已存在,如果存在,次数加1,否则添加到map中
for(mIter=mManagerAgeAndCounts.begin(); mIter!=mManagerAgeAndCounts.end(); ++mIter)
{
if(mIter->first==a)
{
++mIter->second;
}
}
if(mIter==mManagerAgeAndCounts.end())
{
mManagerAgeAndCounts.insert(pair<int,int>(a,1));
}
//将这个可能的三个女孩的年龄组合添加到vecDaughterAge里
vecDaughterAge.push_back(tmp);
}
}
}
cout<<"根据已知条件得出可能的经理年龄和次数的组合:"<<endl;
for(mIter=mManagerAgeAndCounts.begin(); mIter!=mManagerAgeAndCounts.end(); ++mIter)
{
cout<<mIter->first<<" "<<mIter->second<<endl;
}
cout<<endl;
cout<<"根据已知条件得出可能的三个女孩的年龄的组合:"<<endl;
for(vIter=vecDaughterAge.begin(); vIter!=vecDaughterAge.end(); ++vIter)
{
cout<<vIter->x<<" "<<vIter->y<<" "<<vIter->z<<endl;
}
cout<<endl;
int aReal; //经理的真实年龄
cout<<"根据追加判断的条件得出经理的年龄和三个女孩的年龄:"<<endl;
for(mIter=mManagerAgeAndCounts.begin(); mIter!=mManagerAgeAndCounts.end(); ++mIter)
{
if(mIter->second !=1) //有追加条件,说明次数不可能为1
{
aReal=mIter->first;
cout<<"经理的年龄是:"<<aReal<<endl;
for(vIter=vecDaughterAge.begin(); vIter !=vecDaughterAge.end(); ++vIter)
{
a=(vIter->x)*(vIter->y)*(vIter->z); //求出对应的a
if(a==aReal && (vIter->x > vIter->y && vIter->y >= vIter->z))
{
cout<<"三个女孩的年龄分别为:"<<vIter->x<<" "<<vIter->y<<" "<<vIter->z<<endl;
}
}
}
}
return 0;
}