問題描述:
12枚錢幣,其中一枚是假的。假幣的重量和真幣不同,但是不知道比真幣輕還是重。用天平稱 3 次,找到那枚假幣。
主要思路:
1. 如果天平兩邊重量相同,則說明兩邊的錢幣都是真的;
2. 如果天平兩邊重量不同,則說明其他的硬幣都是真的(因爲只有一枚假幣);
3. 如果有一枚硬幣既出現在輕的一端,也曾出現在重的一端,則說明它是真幣;
注意天平兩端不一定是 4 枚硬幣,幾次 WA 都是這個原因。
源代碼:
#include <iostream>
#include <string>
using namespace std;
int coins[12] = {0};
string scoins = "ABCDEFGHIJKL";
void GetRealCoin(string s)
{
for(int i = 0; i < s.length(); i++)
coins[s[i] - 'A'] = 2;
}
bool CharinString(char c, string s)
{
for(int i = 0; i < s.length(); i++)
{
if(c == s[i])
return true;
}
return false;
}
void GetOthers(string s)
{
for(int i = 0; i < 12; i++)
{
if(!CharinString(scoins[i], s))
coins[i] = 2;
}
}
void GetRealFromLH(string* lightcoins, string* heavycoins)
{
bool lightflag, heavyflag;
for(int i = 0; i < 12; i++)
{
lightflag = false;
heavyflag = false;
for(int j = 0; j < 3; j++)
{
if(CharinString(scoins[i], lightcoins[j]))
lightflag = true;
if(CharinString(scoins[i], heavycoins[j]))
heavyflag = true;
if(lightflag && heavyflag)
coins[i] = 2;
}
}
}
int main()
{
int number = 0;
string left, right, balance;
string lightcoins[3];
string heavycoins[3];
cin >> number;
while(number--)
{
memset(coins, 0, sizeof(coins));
left = right = balance = "";
for(int n = 0; n < 3; n++)
{
lightcoins[n] = "";
heavycoins[n] = "";
}
for(int i = 0; i < 3; i++)
{
cin >> left >> right >> balance;
if(balance == "even")
{
GetRealCoin(left + right);
}
else if(balance == "up")
{
GetOthers(left + right);
lightcoins[i] = right;
heavycoins[i] = left;
}
else if(balance == "down")
{
GetOthers(left + right);
lightcoins[i] = left;
heavycoins[i] = right;
}
}
GetRealFromLH(lightcoins, heavycoins);
int j = 0;
for(int k = 0; k < 12; k++)
{
if(coins[k] != 2)
{
for(j = 0; j < 3; j++)
{
if(CharinString(scoins[k], lightcoins[j]))
{
cout << scoins[k] << " is the counterfeit coin and it is light." << endl;
break;
}
}
if(j == 3)
cout << scoins[k] << " is the counterfeit coin and it is heavy." << endl;
}
}
}
return 0;
}