poj1013 假硬币

描述

Sally Jones 有十几个 Voyageur 银元。然而,只有 11 枚硬币是真正的银元;一枚硬币是伪造的,即使它的颜色和大小使其与真正的银元无法区分。假币与其他硬币的重量不同,但 Sally 不知道它比真币重还是轻。
幸运的是,莎莉有一个朋友借给她一个非常准确的天平秤。这位朋友将允许莎莉称重三下以找到假币。例如,如果 Sally 将两枚硬币相互称重并且天平保持平衡,那么她就知道这两枚硬币是真实的。现在如果莎莉重
一枚真硬币与第三枚硬币之间的天平不平衡,那么莎莉知道第三枚硬币是假币,她可以分别根据放置它​​的天平是上升还是下降来判断它是轻还是重。
通过仔细选择她的称量,Sally 能够确保她能找到恰好三个称量的假币。

输入

输入的第一行是一个整数 n (n > 0),指定要遵循的案例数。每个案例由三行输入组成,每个称重行。Sally 用字母 A--L 识别了每枚硬币。关于称重的信息将由两串字母给出,然后是单词“up”、“down”或“even”中的一个。第一串字母代表左边余额中的硬币;第二个字符串,硬币在正确的平衡。(Sally 将始终将相同数量的硬币放在右侧天平上和左侧天平上。)第三个位置的单词将说明天平的右侧是上升、下降还是保持平衡。

输出

对于每种情况,输出将通过字母识别假币并判断它是重还是轻。解决方案将始终是唯一确定的。

样本输入

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;
bool IsFake(char c,bool light);	//判断假设是否成立,成立返回true,不成立返回false 
char Left[3][7];	//用于存储三次左侧存放的硬币 
char Right[3][7];	//用于存储三次右侧存放的硬币 
char Result[3][7];	//用于存储三次称量的结果
int main()
{
	int n;
	cin>>n;
	while(n--){
		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))	//假设c是假币且是轻的 
				{
					cout<<c<<" is the counterfeit coin and it is light.\n";
				}
				else if(IsFake(c,false))	//假设c是假币且是重的 
				{
					cout<<c<<" is the counterfeit coin and it is heavy.\n";
				}
			}
		}
}
bool IsFake(char c,bool light)
{
	for(int i=0;i<3;i++)
	{
		char *pLeft,*pRight; 
		if(light)
		{
			pLeft=Left[i];	//假设硬币轻的情况 
			pRight=Right[i];
		}
		else 
		{
			pLeft=Right[i];	//假设硬币重的情况,为了不再写一条switch所以将指针互换 
			pRight=Left[i];
		}
		switch(Result[i][0]){
			case 'e': 
					if(strchr(pRight,c) || strchr(pLeft,c)) return false;	//平衡,如果c在天平中则说明c不是假的 
					break;
			case 'u':
					if(strchr(pRight,c)==NULL) return false;	//右侧轻,如果c在右侧说明假设成立,为空则c不在右侧假设错误 
					break;	
			case 'd':
					if(strchr(pLeft,c)==NULL) return false;		//右侧重,左侧轻,如果c在左侧说明假设成立,为空则c不在左侧假设错误  
					break;
		}
	}
	return true;
}

成功AC,但还有更省事一点的,就是当出现平衡状态时,说明在称重的硬币都是真的,所以可以跳过这些硬币,不用遍历十二枚硬币来判断。代码就不给出了,大家可以自己去试试。

cjl

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值