题目来源:http://poj.org/problem?id=1013
题目大意:有12枚硬币,其中有一枚假币。所有钱币的外表都一样,所有真币的重量都一样,假币的重量与真币不同,但我们不知道假币的重量是比真币轻还是重。现在有一个很准确的天平,我们可以用这个天平称3次来找到那枚假币。只要仔细选择三次称的方式,总可以再三次之内找出那枚假币。
输入:第一行一个正整数n表示样例个数。接下来每三行为一个测试样例。每行为一次称的结果。每枚硬币被编号为A--L。称量的结果有三种,分别用“up”、“down”和“even”表示。第一个字符串表示天平左边的硬币,第二个字符串表示右边的硬币。左边和右边的硬笔数总是相等的。第三个字符串的单词表明天平右边的状态。
输出:对于每个测试用例,输出假币的编号和这枚假币是比真币重还是轻。格式依照Sample output.
Sample Input
1 ABCD EFGH even ABCI EFJK up ABIJ EFGH even
Sample Output
K is the counterfeit coin and it is light.
注意到以下几点:
1.某次称量天平平衡,说明天平两端都是真币.
2.某次天气不平衡,说明这次称量没有用到的都是真币.
3.如果假币比真币重,则假币只可能每次都出现在天平重的一端(轻则相反),所以若某硬币一次出现在重的一端另一次出现在轻了一端则为真币
给每枚硬币一个编码,表示其状态。-1表示没有出现,1表示是真币,0表示可能是假币,且比真币轻,2表示可能是假币,且比真币重。
依据上述观察,每称一次更新一次硬币状态。最终只有一枚硬币不为1。具体见代码。
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1013 Counterfeit Dollar 3 // Memory: 268K Time: 16MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 #include <string> 9 using namespace std; 10 11 int main() { 12 int n; 13 cin >> n; 14 for (int i = 0; i < n; i++) { 15 string l[3], r[3], b[3]; 16 int result[12]; 17 bool light = false; 18 for (int i = 0; i < 12; i++) { 19 result[i] = -1;//未出现 20 } 21 cin >> l[0] >> r[0] >> b[0] >> l[1] >> r[1] >> b[1] >> l[2] >> r[2] >> b[2]; 22 23 for(int i = 0; i < 3; i++) { 24 if (b[i].compare("even") == 0) { 25 for (int j = 0; j < l[i].size(); j++) { 26 result[l[i][j] - 'A'] = 1; 27 } 28 for (int j = 0; j < r[i].size(); j++) { 29 result[r[i][j] - 'A'] = 1; 30 } 31 } else if (b[i].compare("up") == 0) { 32 bool mark[12] = {false, false, false, false, false, false, 33 false, false, false, false, false, false}; 34 for (int j = 0; j < l[i].size(); j++) { 35 if (result[l[i][j] - 'A'] == -1) { 36 result[l[i][j] - 'A'] = 2; 37 } else if (result[l[i][j] - 'A'] == 0) { 38 result[l[i][j] - 'A'] = 1; 39 } 40 mark[l[i][j] - 'A'] = true; 41 } 42 for (int j = 0; j < r[i].size(); j++) { 43 if (result[r[i][j] - 'A'] == -1) { 44 result[r[i][j] - 'A'] = 0; 45 } else if (result[r[i][j] - 'A'] == 2) { 46 result[r[i][j] - 'A'] = 1; 47 } 48 mark[r[i][j] - 'A'] = true; 49 } 50 for (int t = 0 ; t < 12; t++) { 51 if (mark[t] == false) { 52 result[t] = 1; 53 } 54 } 55 } else { 56 bool mark[12] = {false, false, false, false, false, false, 57 false, false, false, false, false, false}; 58 for (int j = 0; j < l[i].size(); j++) { 59 if (result[l[i][j] - 'A'] == -1) { 60 result[l[i][j] - 'A'] = 0; 61 } else if (result[l[i][j] - 'A'] == 2) { 62 result[l[i][j] - 'A'] = 1; 63 } 64 mark[l[i][j] - 'A'] = true; 65 } 66 for (int j = 0; j < r[i].size(); j++) { 67 if (result[r[i][j] - 'A'] == -1) { 68 result[r[i][j] - 'A'] = 2; 69 } else if (result[r[i][j] - 'A'] == 0) { 70 result[r[i][j] - 'A'] = 1; 71 } 72 mark[r[i][j] - 'A'] = true; 73 } 74 for (int t = 0 ; t < 12; t++) { 75 if (mark[t] == false) { 76 result[t] = 1; 77 } 78 } 79 } 80 } 81 for (int i = 0; i < 12; i++) { 82 if (result[i] == 0) { 83 cout << char(i + 'A') << " is the counterfeit coin and it is light." << endl; 84 break; 85 } else if (result[i] == 2) { 86 cout << char(i + 'A') << " is the counterfeit coin and it is heavy." << endl; 87 break; 88 } 89 } 90 } 91 system("pause"); 92 }
附Discuss里面的一些测试数据:
1 sample input 2 12 3 ABCD EFGH even 4 ABCI EFJK up 5 ABIJ EFGH even 6 AGHL BDEC even 7 JKI ADE up 8 J K even 9 ABCDEF GHIJKL up 10 ABC DEF even 11 I J down 12 ABCDEF GHIJKL up 13 ABHLEF GDIJKC down 14 CD HA even 15 A B up 16 B A down 17 A C even 18 A B up 19 B C even 20 DEFG HIJL even 21 ABC DEJ down 22 ACH IEF down 23 AHK IDJ down 24 ABCD EFGH even 25 AB IJ even 26 A L down 27 EFA BGH down 28 EFC GHD even 29 BA EF down 30 A B up 31 A C up 32 L K even 33 ACEGIK BDFHJL up 34 ACEGIL BDFHJK down 35 ACEGLK BDFHJI down 36 ACEGIK BDFHJL up 37 ACEGIL BDFHJK down 38 ACEGLK BDFHJI up 39 40 sample output 41 K is the counterfeit coin and it is light. 42 I is the counterfeit coin and it is heavy. 43 I is the counterfeit coin and it is light. 44 L is the counterfeit coin and it is light. 45 B is the counterfeit coin and it is light. 46 A is the counterfeit coin and it is heavy. 47 A is the counterfeit coin and it is light. 48 L is the counterfeit coin and it is heavy. 49 A is the counterfeit coin and it is light. 50 A is the counterfeit coin and it is heavy. 51 L is the counterfeit coin and it is light. 52 K is the counterfeit coin and it is heavy.