`
taojianrong
  • 浏览: 11264 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

POJ1013 C++解法

阅读更多

大致题意:

有一打(12枚)硬币,其中有且仅有1枚假币,11枚真币

用A~L作为各个硬币的代号

假币可能比真币略轻,也可能略重

现在利用天枰,根据Input输入的3次称量,找出假币,并输出假币是轻还是重。

 

 

解题思路:

模拟法要考虑的情况较繁琐,可利用简单的逻辑推理进行解题。

 

 

注意Input一行代表一次称量,每行有三个字符串,分别为

Left right status

代表该次称量时,天枰左盘放的硬币、天枰右盘放的硬币、天枰右盘的状态

 

 

共三种状态:

Up:右盘上升,说明右盘可能有轻假币,也可能左盘有重假币。

Down:右盘下降,说明右盘可能有重假币,也可能左盘有轻假币。

Even:右盘与左盘平衡,由于假币有且仅有1枚,则说明此时天枰两边的硬币全为真币。

 

注意题目的字眼:

1、 有且仅有1枚假币

2、 假币相对于真币的重量,可能轻可能重

3、 只称量3次,且称量3次恰好且必能找到假币

4、 每次称量时天枰两边的硬币数目一样

5、 选取哪些硬币称量由input决定

 

从3、4、5可知,由于无法知道每次选取称量的硬币,那么3次称量可能只选用了几个硬币,也可能仅有一两个硬币没有选上,那么用模拟法去记录每次用于称量的硬币的状态(真假,其中假币又有轻重之分)并推导没有被称量的硬币状态(或状态变化)是很困难的,虽然人很容易做到这点,但计算机却很难去“推导”,因为称量硬币的方法是无规律的且非常多。

 

那么只能通过适当转化问题后用另一种有效的方法去解决。

 

虽然称量硬币的方法是无规律且未知的,但是称量硬币后的结果却只有3个,up、down和 even。且当出现even时,天枰两边的硬币必然都为真币,假币必定在余下的硬币之间(这是因为假币有且只有一枚),那么我们就可以定义一个标记数组 zero[]去标记even时的真币,在以后的处理把他们排除在外。

而唯一难以处理的是up和down的状态,因为假币可能轻可能重,则这两种状态都无法得知究竟假币出现在天枰的哪边。

 

 

处理up和down状态方法:

当出现up或down状态时,天枰两边的所有硬币都应该被怀疑为假币(已标记必定为真币的硬币不必被怀疑)。

首先time[]记录每个硬币的被怀疑程度,time[i]=0表示该硬币i不被怀疑(即其可能为真币)。定义在up状态盘的硬币为“轻怀疑假币”,通过“--”操作加深其被怀疑为轻假币的程度,“负号”为轻假币的怀疑方向;在down状态盘的硬币为“重怀疑假币”,通过“++”操作加深其被怀疑为重假币的程度,“正号”为重假币的怀疑方向。

那么若一枚真币被怀疑为“轻假币”时,它就可能通过下次称量通过“++”操作取消嫌疑了。初始化所有硬币的怀疑程度均为0。

称量完毕后,找出被怀疑程度最大(注意取绝对值)的硬币,它就是假币。而当其怀疑方向为正时,则其为重假币。为负时,为轻假币。

 

//Memory Time
//252K   0MS

#include<iostream>
#include<cmath>
using namespace std;

int main(void)
{
	int cases;
	cin>>cases;
	for(int c=1;c<=cases;c++)
	{
		char left[3][7],right[3][7],status[3][7];

		int time['L'+1]={0};  //标记各个字母被怀疑的次数
		bool zero['L'+1]={false};  //标记绝对为真币的字母(令天枰平衡的所有字母)

		for(int k=0;k<3;k++)
			cin>>left[k]>>right[k]>>status[k];

		for(int i=0;i<3;i++)
		{
			switch(status[i][0])  //检查天枰状态
			{
			    case 'u':     //up,天枰左重右轻
					{
						for(int j=0;left[i][j];j++)
						{
							time[ left[i][j] ]++;  //左重
							time[ right[i][j] ]--;  //右轻
						}
						break;
					}
				case 'd':     //down,天枰左轻右重
					{
						for(int j=0;left[i][j];j++)
						{
							time[ left[i][j] ]--;  //左轻
							time[ right[i][j] ]++;  //右重
						}
						break;
					}
				case 'e':     //down,天枰平衡
					{
						for(int j=0;left[i][j];j++)
						{
							zero[ left[i][j] ]=true;   //绝对真币
							zero[ right[i][j] ]=true;   //绝对真币
						}
						break;
					}
			}
		}

		int max=-1;  //查找被怀疑程度最高的硬币(假币)
		char alpha;
		for(int j='A';j<='L';j++)
		{
			if(zero[j])  //绝对真币
				continue;

			if(max<=abs(time[j]))
			{
				max=abs(time[j]);
				alpha=j;
			}
		}

		cout<<alpha<<" is the counterfeit coin and it is ";
		if(time[alpha]>0)
			cout<<"heavy."<<endl;
		else
			cout<<"light."<<endl;
	}
	return 0;
}

  

分享到:
评论

相关推荐

    C++经典代码大全,自编,很多poj上的经典题目

    《C++经典代码大全》是一份集合了作者自编的C++编程实例,主要涵盖了POJ(Problem Set of Peking University)在线判题系统上的众多经典编程题目。这份资源对于初学者来说尤其宝贵,因为它提供了丰富的实践案例,...

    田忌赛马: POJ 2287(贪心解法)

    《田忌赛马:POJ 2287 贪心解法解析》 在计算机科学领域,算法是解决问题的核心。"田忌赛马"这个题目来源于古代中国的一个著名故事,而在这个故事的基础上,被引入到了编程竞赛的场景中。POJ(Programming Online ...

    西北工业大学C++POJ答案

    【标题】"西北工业大学C++ POJ答案"指的是西北工业大学的学生或教师分享的一份C++编程语言在解决Programming Online Judge(POJ)平台上的题目时的解答集合。POJ是一个在线编程竞赛平台,主要面向大学生和编程爱好者...

    poj3717题的代码

    在这种情况下,"ai3717"可能是C++、Java或其他编程语言的源代码文件,包含了作者对POJ3717问题的解决方案。 由于没有给出具体的题目内容和代码,我们无法深入讨论解题策略或算法实现。不过,一般来说,解决POJ上的...

    POJ代码,用C++编写,是AC过的代码!

    根据【压缩包子文件的文件名称列表】:“北大题”,我们可以推测这个压缩包内包含的是一系列与北京大学POJ题库相关的题目解法代码。每个文件可能对应一个具体的题目,文件名可能是题目的编号或者题目描述的一部分。 ...

    北京大学poj题目解题代码

    北京大学的POJ题目解题代码集合是一份宝贵的资源,它涵盖了ACM(国际大学生程序设计竞赛)中的许多问题,旨在帮助学生和编程爱好者提升算法理解与编程技能。POJ(Problem Set for Online Judges)是中国最早的在线...

    POJ1010-STAMPS

    2. "POJ1010-STAMPS.doc":这是一个文档文件,很可能包含了对问题的详细解释、解题思路、算法流程图、时间复杂度分析等内容,对于学习和理解这个问题的解法非常有帮助。 综合以上信息,我们可以推断,"POJ1010-...

    POJ2531-Network Saboteur

    【压缩包子文件的文件名称列表】中,"POJ2531-Network Saboteur.cpp"是用C++编写的源代码文件,包含了实现解题逻辑的程序;"POJ2531-Network Saboteur.doc"可能是一个文档文件,详细解释了解题思路、算法描述或者...

    poj1000-1200部分代码

    "POJ 1000-1200大部分资源代码"是一个专门为初学者准备的宝藏库,其中包含了C++和JAVA两种编程语言的源码。POJ,全称是Programming Online Judge,是一个知名的在线编程竞赛平台,它为程序员提供了丰富的编程题目,...

    POJ3080-Blue Jeans

    【压缩包子文件的文件名称列表】中,"POJ3080-Blue Jeans.cpp" 是提交给POJ平台的AC代码,可能包含了上述的动态规划解法,使用C++语言实现。"POJ3080-Blue Jeans.doc" 可能是解题报告文档,详细解释了解题过程和思路...

    poj 1000-3000部分代码

    POJ是一个以C、C++和Java为主要语言的在线编程竞赛平台,它提供了各种算法和逻辑思维的练习题目,旨在提升程序员的编程能力和解决问题的能力。 描述中的“网上收集”表明这个压缩包里的代码是从网络上搜集而来,...

    POJ2151-Check the difficulty of problems

    首先,我们需要理解POJ(北大在线评测系统)是一个供程序员练习和提交代码的平台,主要支持C、C++和Java语言。它提供各种不同难度级别的编程题目,帮助用户提升算法和编程能力。 题目“Check the difficulty of ...

    poj题目分类打包题库题目分类

    ACM竞赛旨在提升大学生的算法设计和编程能力,因此题目的难度和复杂性较高,涉及的编程语言通常包括C、C++、Java等。这个描述中的"来源网络"和"自己整理一部分"说明了题目的收集方式,既包括网络上公开的资源,也有...

    POJ1338.rar_poj1338

    【压缩包子文件的文件名称列表】:POJ1338 这个文件可能是包含解题代码的源文件,通常使用的编程语言可能有C++、Java、Python等。解题代码会清晰地展示如何根据题目要求构建算法,实现数据结构,以及如何优化时间...

    acm竞赛----北大poj详细解题报告

    它支持多种编程语言,如C、C++、Java等,参赛者可以提交代码并立即获取运行结果和评测报告,有利于选手自我检验和提高。 三、解题报告的重要性 解题报告是ACM竞赛学习中的重要参考资料。它通常包含以下几个部分: 1...

    北大acm题解(poj题目分析)

    5. 思路拓展:讨论可能的优化方法,或者对比不同解法的优缺点,帮助读者深化对问题本质的理解。 通过阅读《北大ACM题解》,你可以学习到如何分析问题,选择合适的算法,以及编写高效的代码。这将对你在ACM竞赛中的...

    poj.rar_poj

    在"poj.rar"这个压缩包中,包含的是用户完成的POJ题目源代码,可能是用C、C++或Java等编程语言编写的。 【描述】"我最近做的几个poj题目源代码,可能比较简单" 暗示了这些代码是作者近期解决的一些基础或入门级别的...

    POJ1083-Moving Tables

    【压缩包子文件的文件名称列表】中的"POJ1083-Moving Tables.cpp"是C++语言编写的源代码文件,包含了解决该问题的算法实现。".cpp"扩展名表明这是一段C++代码,可能使用了STL(Standard Template Library)等C++特性...

    POJ1716-Integer Intervals【Difference Constraints】

    1. "POJ1716-Integer Intervals【Difference Constraints】.cpp":这可能是基于差分约束系统理论的C++代码实现,它可能采用了动态规划或者线性规划的方法来解决问题。 2. "POJ1716-Integer Intervals【Greed】.cpp...

    poj_3310.rar_3310_poj

    4. **编程实践**:通过"poj_3310.txt"中的代码,我们可以看到问题的代码实现,这可能涉及C++、Java或Python等常见编程语言,学习如何将算法转化为实际的程序。 5. **代码优化**:作者可能会分享代码优化的技巧,...

Global site tag (gtag.js) - Google Analytics