POJ1013 Counterfeit Dollar

题目来源: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 }
View Code

附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.
Test data & answer
posted @ 2013-07-31 00:39  小菜刷题史  阅读(702)  评论(0编辑  收藏  举报