假幣問題(北大MOOC程序設計與算法二 第一週例題)

假幣問題

有12枚硬幣。其中有11枚真幣和1枚假幣。假幣看起來和真幣沒有區別,只有重量不同。但不知道假幣比真幣輕還是重。現在用一架天平稱了這些硬幣三次,告訴你稱的結果,請你找出假幣並確定假幣是輕是重(數據保證一定能找出來)。

輸入

第一行時測試數據組數。
每組數據有三行,每行表示一次稱量的結果。硬幣標號爲A-L。每次稱量的結果用三個以空格隔開的字符串表示:天平左邊放置的硬幣、天平右邊放置的硬幣、平衡狀態。其中平衡狀態用“up’’, “down”, 或 “even”表示, 分別爲右端高、右端低和平衡。天平左右的硬幣數總是相等的

輸出

輸出哪一個標號的硬幣是假幣,並說明它比真幣輕還是重。

輸入樣例

1
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even

輸出樣例

K is the counterfeit coin and it is light.

解題思想

對於每一枚硬幣先假設它是輕的,看是否符合稱重結果。如果符合,問題解決。如果不符合,就假設它是重的,看是否符合稱重結果。把所有硬幣都試一次。

代碼

#include<iostream>
#include<cstring>
using namespace std;
char Left[3][7];	//左邊天平 
char Right[3][7];	//右邊天平 
char result[3][7];	//結果
bool isfake(char c,bool light);	//light爲真表示假設假幣爲輕 
int main()
{
	int t;
	cin>>t;
	while(t--){
		for(int i=0;i<3;++i)
			cin>>Left[i]>>Right[i]>>result[i];
		for(char c='A';c<='L';c++){
			if(isfake(c,true)){
				cout<<c<<"is the counterfeit coin and it is light.\n";
				break;
			}
			else if(isfake(c,false)){
				cout<<c<<"is the counterfeit coin and it is light.\n";
				break;
			}
		}
	} 
	return 0; 
}

bool isfake(char c,bool light){
	for(int i=0;i<3;i++){
		char *pleft,*pright;
		//因爲天平反映的是右邊的情況
		//當假設假幣輕時,若假幣在右邊則右邊up,在左邊則右邊down
		//當假設假幣重時,若假幣在右邊則右邊down,在左邊則右邊up
		//當假設假幣重時,用指針調換天平的兩側,使得若假幣在右邊則右邊up 
		if(light){
			pleft=Left[i];
			pright=Right[i];
		}
		else{
			pleft=Right[i];
			pright=Left[i];
		}
		switch(result[i][0]){	//天平右邊的情況 
			case 'u':	//右邊輕 
				if(strchr(pright,c)==NULL)
					return false;
				break;
			case 'e':
				if(strchr(pleft,c)||strchr(pright,c))
					return false;
				break;
			case 'd':	//右邊重 
				if(strchr(pleft,c)==NULL)
					return false;
				break;
		}
	}
	return true;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章