POJ1013 Counterfeit Dollar

本文介绍了一个经典的逻辑推理问题:如何从12个银币中找出唯一一个重量异常的银币,并判断其是否较轻或较重。通过三次称重实验,利用位运算进行数据状态更新,最终确定异常银币及其状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

12个银子,一个重了或轻了,其它重量都一样。现将数目相等的两堆银子放到天平上称,究竟是哪些银子以及称量的具体结果都已知。问重或轻的银子是哪个,重了还是轻了。

思路

调查员是怎样系统分析问题的?思路便是缩小范围、运用排除法。

用整数压缩状态分别表示哪些银子可能轻了,哪些可能重了。天平平衡时,两侧的所有银子都不可能是假银子;不平衡时,轻银子只有可能在低的那一边的银子中,重银子同理。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <cassert>
using namespace std;

int main()
{
#ifdef _DEBUG
	freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
	int caseCnt;
	cin >> caseCnt;
	while (caseCnt--)
	{
		int light = (1 << 12) - 1, heavy = (1 << 12) - 1;
		string a, b, condition;
		for (int i = 0; i < 3; i++)
		{
			cin >> a >> b >> condition;
			int left = 0, right = 0;
			for (int i = 0; i < a.size(); i++)
				left |= (1 << a[i] - 'A');
			for (int i = 0; i < b.size(); i++)
				right |= (1 << b[i] - 'A');
			if (condition == "even")
			{
				light = light & (~left) & (~right);
				heavy = heavy & (~left) & (~right);
			}
			else
			{
				if (condition == "up")
					swap(left, right);
				light &= left;
				heavy &= right;
			}
		}
		int lightAns = -1;
		for(int i = 0; i < 12; i++)
			if ((1 << i) & light)
			{
				if (light - (1 << i) == 0)
					lightAns = i;
				break;
			}
		int heavyAns = -1;
		for(int i=0; i<12; i++)
			if ((1 << i) & heavy)
			{
				if (heavy - (1 << i) == 0)
					heavyAns = i;
				break;
			}
		assert(lightAns == -1 && heavyAns >= 0 || heavyAns == -1 && lightAns >= 0);
		if (lightAns >= 0)
			printf("%c is the counterfeit coin and it is light.\n", lightAns + 'A');
		else
			printf("%c is the counterfeit coin and it is heavy.\n", heavyAns + 'A');
	}

	return 0;
}

  

转载于:https://www.cnblogs.com/headboy2002/p/9127641.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值