很坑爹 。。。
-------------------------------------------------------------------------------------------------------
- Time Limit:
- 1000ms
- Memory Limit:
- 65536kB
- Description
- 賽利有12枚銀幣。其中有11枚真幣和1枚假幣。假幣看起來和真幣沒有區別,但是重量不同。但賽利不知道假幣比真幣輕還是重。於是他向朋友借了一架天平。朋友希望賽利稱三次就能找出假幣並且確定假幣是輕是重。例如:如果賽利用天平稱兩枚硬幣,發現天平平衡,說明兩枚都是真的。如果賽利用一枚真幣與另一枚銀幣比較,發現它比真幣輕或重,說明它是假幣。經過精心安排每次的稱量,賽利保證在稱三次後確定假幣。
- Input
-
第一行有一個數字n,表示有n組測試用例。
對於每組測試用例:
輸入有三行,每行表示一次稱量的結果。賽利事先將銀幣標號爲A-L。每次稱量的結果用三個以空格隔開的字符串表示:天平左邊放置的硬幣 天平右邊放置的硬幣 平衡狀態。其中平衡狀態用``up'', ``down'', 或 ``even''表示, 分別爲右端高、右端低和平衡。天平左右的硬幣數總是相等的。 - Output
- 輸出哪一個標號的銀幣是假幣,並說明它比真幣輕還是重(heavy or light)。
- Sample Input
-
1 ABCD EFGH even ABCI EFJK up ABIJ EFGH even
Sample Output
K is the counterfeit coin and it is light.
---------------------------------------------------------------------
最開始的想法爲先將所有正常的硬幣找出來(even兩端的),然後對於三次稱量結果,讀每次稱量左右的硬幣,如果硬幣不是正常的,那麼根據稱量的結果(up或者down)可以判斷出硬幣的輕重。這種想法對於題目中例子能夠判斷出正確結果,但是對於測試數據如
ABCD EFGH even
IJ KA up
JK AB up
不能得出正確結果,首先只能判斷出正常的八個硬幣,其餘的四個硬幣都出現在了up或者down的語句中,這樣的結果是不正確的。
然後考慮將稱量的語句分類,將生成up_left,up_right,down_left,down_right字符串,每次讀到了相應語句,則將左右的字母分別加到相應的字符串末尾,然後對於12個硬幣,依次判斷
for(i=0;i<12;i++){
c='A'+i;
if(even.toString().indexOf(c)!=-1)
continue;
if(!up_right.toString().equals("")&&!down_left.toString().equals("")){
if(up_right.toString().indexOf(c)!=-1&&down_left.toString().indexOf(c)!=-1){
sresult=(char)c+" is the counterfeit coin and it is light.";
break;
}
}
else if(up_right.toString().equals("")&&!down_left.toString().equals("")){
if(down_left.toString().indexOf(c)!=-1){
sresult=(char)c+" is the counterfeit coin and it is light.";
break;
}
}
else if(down_left.toString().equals("")&&!up_right.toString().equals("")){
if(up_right.toString().indexOf(c)!=-1){
sresult=(char)c+" is the counterfeit coin and it is light.";
break;
}
}
if(!up_left.toString().equals("")&&!down_right.toString().equals("")){
if(up_left.toString().indexOf(c)!=-1&&down_right.toString().indexOf(c)!=-1){
sresult=(char)c+" is the counterfeit coin and it is heavy.";
break;
}
}
else if(up_left.toString().equals("")&&!down_right.toString().equals("")){
if(down_right.toString().indexOf(c)!=-1){
sresult=(char)c+" is the counterfeit coin and it is heavy.";
break;
}
}
else if(down_right.toString().equals("")&&!up_left.toString().equals("")){
if(up_left.toString().indexOf(c)!=-1){
sresult=(char)c+" is the counterfeit coin and it is heavy.";
break;
}
}
}
結果對於測試數據
ABCD
EFGH even
IJ KA up
JK AB up
還是不能得到正確的結果,因爲此數據中只有up,那麼一旦一個硬幣出現在了up_left中,那麼它就會被判斷爲重。
然後看了書上的思路,發現是對於每一個硬幣,放入三條稱量語句中判斷它是否輕或者重,
int isLight(char c)
{
int j;
for (j=0;j<3;j++)
{
if (s[j][2][0]=='u')
{
//如果該字母出現在up右端(高的那端),那麼它就不是輕的
if (strchr(s[j][1],c)!=NULL)
return false;
}
if (s[j][2][0]=='e')
{
//如果該字母出現在平衡稱量語句中
if (strchr(s[j][0],c)||strchr(s[j][1],c))
return false;
}
if (s[j][2][0]=='d')
{
//如果該字母出現在down左端(高的那端),那麼它就不是輕的
if (strchr(s[j][0],c)!=NULL)
return false;
}
}
return true;
}
但是這種思路其實是錯誤的,出現在高的那端除了輕的硬幣還可能是正常的硬幣。
於是改代碼如下
int isLight(char c)
{
int j;
for (j=0;j<3;j++)
{
if (s[j][2][0]=='u')
{
//如果該字母沒有出現在up右端(高的那端),那麼它就一定不是輕的
if (strchr(s[j][1],c)==NULL)
return false;
}
if (s[j][2][0]=='e')
{
if (strchr(s[j][0],c)||strchr(s[j][1],c))
return false;
}
if (s[j][2][0]=='d')
{
//如果該字母沒有出現在down左端(高的那端),那麼它就一定不是輕的
if (strchr(s[j][0],c)==NULL)
return false;
}
}
return true;
}
另一個函數int isHeavy(char c)同理
#include <iostream>
#include "string.h"
using namespace std;
char s[3][3][13];
int isLight(char c)
{
int j;
for (j=0;j<3;j++)
{
if (s[j][2][0]=='u')
{
//如果該字母沒有出現在up右端(高的那端),那麼它就一定不是輕的
if (strchr(s[j][1],c)==NULL)
return false;
}
if (s[j][2][0]=='e')
{
if (strchr(s[j][0],c)||strchr(s[j][1],c))
return false;
}
if (s[j][2][0]=='d')
{
//如果該字母沒有出現在down左端(高的那端),那麼它就一定不是輕的
if (strchr(s[j][0],c)==NULL)
return false;
}
}
return true;
}
int isHeavy(char c)
{
int j;
for (j=0;j<3;j++)
{
if (s[j][2][0]=='u')
{
if (strchr(s[j][0],c)==NULL)
return false;
}
if (s[j][2][0]=='e')
{
if (strchr(s[j][0],c)||strchr(s[j][1],c))
return false;
}
if (s[j][2][0]=='d')
{
if (strchr(s[j][1],c)==NULL)
return false;
}
}
return true;
}
int main()
{
int T,i;
char c;
cin>>T;
while(T--)
{
cin>>s[0][0]>>s[0][1]>>s[0][2]>>s[1][0]>>s[1][1]>>s[1][2]>>s[2][0]>>s[2][1]>>s[2][2];
for (i=0;i<12;i++)
{
c=(char)(i+'A');
if (isLight(c))
{
cout<<c<<" is the counterfeit coin and it is light."<<endl;
break;
}
if (isHeavy(c))
{
cout<<c<<" is the counterfeit coin and it is heavy."<<endl;
break;
}
}
}
}