现有八枚银币a b c d e f g h,已知其中一枚是假币,其重量不同于真币,但不知是较轻或较重,如何使用天平以最少的比较次数,决定出哪枚是假币,并得知假币比真币较轻或较重。
分析:首先将八枚银币分为abc、def和gh三组:
(1) 如果abc = def,则g或h为假币,两步即可得到结果。
(2) 如果abc〉def,则接下来比较ad与bf
a) 如果ad = bf,则假币为c或e,且c大于e。将c或e中任何一个与正常银币比较即可得到结果。
b) 如果ad > bf,则假币为a或f,且a大于f。将a或f中任何一个与正常银币比较即可得到结果。
c) 如果ad < bf,则假币为b或d,且b大于d。将b或d中任何一个与正常银币比较即可得到结果。
综上所述,三步即可找到那枚假币并确定其重量与正常币的关系。
C++参考代码如下,入口函数test()。
class CEightCoin
{
public:
CEightCoin(void);
~CEightCoin(void);
public:
int coin[8];
public:
void test();
void comp(int i, int j, int k);
};
CEightCoin::CEightCoin(void)
{
for (int i = 0; i < 8; i++)
{
coin[i] = 1;
}
srand((unsigned)time(0));
int rd = rand() % 8;
if (rand() % 2)
{
coin[rd] += 1;
}
else
{
coin[rd] -= 1;
}
for (int i = 0; i < 8; i++)
{
std::cout<<coin[i]<<" ";
}
std::cout<<std::endl;
}
CEightCoin::~CEightCoin(void)
{
}
void CEightCoin::test()
{
int i = 0;
if (coin[0] + coin[1] + coin[2] == coin[3] + coin[4] + coin[5])
{
if (coin[6] > coin[7])
{
comp(6, 7, 0);
}
else
{
comp(7, 6, 0);
}
}
else if (coin[0] + coin[1] + coin[2] > coin[3] + coin[4] + coin[5])
{
if (coin[0] + coin[3] == coin[1] + coin[4])
{
//2或5为假币,且2号大于5号
comp(2, 5, 0);
}
else if (coin[0] + coin[3] > coin[1] + coin[4])
{
//0或4号为假币,且0号大于4号
comp(0, 4, 1);
}
else
{
//1号或3号为假币,且1号大于3号
comp(1, 3, 0);
}
}
else
{
if (coin[0] + coin[3] == coin[1] + coin[4])
{
//2号或5号为假币,且5号大于2号
comp(5, 2, 0);
}
else if (coin[0] + coin[3] > coin[1] + coin[4])
{
//1号或3号为假币,且3号大于1号
comp(3, 1, 0);
}
else
{
//0号或4号为假币,且4号大于0号
comp(4, 0 ,1);
}
}
}
void CEightCoin::comp(int i, int j, int k)
{
if (coin[i] > coin[k])
{
std::cout<<"假币"<<i<<"重"<<std::endl;
}
else
{
std::cout<<"假币"<<i<<"轻"<<std::endl;
}
}