POJ 1013 Counterfeit Dollar 简单枚举

【题意简述】:赛利有 12 枚银币。其中有 11 枚真币和 1 枚假币。假币看起来和真币没有区别,但是重量不同。但赛利不知道假币比真币轻还是重。于是他向朋友借了一架天平。朋友希望赛利称三次就能找出假币并且确定假币是轻是重。例如:如果赛利用天平称两枚硬币,发现天平平衡,说明两枚都是真的。如果赛利用一枚真币与另一枚银币比较,发现它比真币轻或重,说明它是假币。经过精心安排每次的称量,赛利保证在称三次后确定假币。

【思路】:此题中赛利已经设计了正确的称量方案,保证从三组称量数据中能得到唯一的答案。答案可以用两个变量表示:x假币的标号、w假币是比真币轻还是比真币重。x 共有 12 种猜测;w 有 2 种猜测。根据赛利设计的称量方案,(x,w )的 24 种猜测中,只有唯一的猜测与三组称量数据都不矛盾。因此,如果猜测(x,w )满足下列条件,这个猜测就是要找的答案:
在称量结果为"even'' 的天平两边,没有出现 x ;
如果 w 表示假币比真币轻,则在称量结果为"up'' 的天平右边一定出现 x、在称量结果为"down'' 的天平左边一定出现 x
如果 w 表示假币比真币重,则在称量结果为"up'' 的天平左边一定出现 x、在称量结果为"down'' 的天平右边一定出现 x
具体实现时,要注意两点:
1) 选择合适的算法
对于每一枚硬币 x 逐个试探:

x 比真币轻的猜测是否成立?猜测成立则进行输出。

x 比真币重的猜测是否成立?猜测成立则进行输出。

/* 132K 0Ms */
#include<iostream>
#include<cstring>
using namespace std;

char lef[3][7],righ[3][7],result[3][5];

bool isHeavy(char);
bool isLight(char);

int main()
{
	int n;
	char c;
	scanf("%d",&n);
	while(n--)
	{
		for(int i =0 ;i<3;i++)
			scanf("%s%s%s",lef[i],righ[i],result[i]);
		for(c = 'A';c<='L';c++)
		{
			if(isLight(c))
			{
				printf("%c is the counterfeit coin and it is light.\n", c);
				break;
			}
			if(isHeavy(c))
			{
				printf("%c is the counterfeit coin and it is heavy.\n", c);
				break;
			}
		}
	}
	return 0;
}

bool isLight(char x)
{
	int i;
	for(i = 0;i<3;i++)
		switch(result[i][0])
		{
			case 'u':if(strchr(righ[i],x) == NULL) return false;
				break;
			case 'e':if(strchr(righ[i],x) != NULL||strchr(lef[i],x) != NULL) return false;
				break; 
			case 'd':if(strchr(lef[i],x) == NULL) return false;
		}
	return true;
}

bool isHeavy(char x)
{
	int i;
	for(i = 0;i<3;i++)
		switch(result[i][0])
		{
			case 'u':if( strchr(lef[i], x) == NULL) return false;
				break;
			case 'e':if(strchr(righ[i],x) != NULL||strchr(lef[i], x) != NULL) return false;
				break;
			case 'd':if(strchr(righ[i], x) == NULL) return false;
				break;
		}
		return true;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值