假币问题(北大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;
}

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