大致题意:
有一打(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++经典代码大全》是一份集合了作者自编的C++编程实例,主要涵盖了POJ(Problem Set of Peking University)在线判题系统上的众多经典编程题目。这份资源对于初学者来说尤其宝贵,因为它提供了丰富的实践案例,...
《田忌赛马:POJ 2287 贪心解法解析》 在计算机科学领域,算法是解决问题的核心。"田忌赛马"这个题目来源于古代中国的一个著名故事,而在这个故事的基础上,被引入到了编程竞赛的场景中。POJ(Programming Online ...
【标题】"西北工业大学C++ POJ答案"指的是西北工业大学的学生或教师分享的一份C++编程语言在解决Programming Online Judge(POJ)平台上的题目时的解答集合。POJ是一个在线编程竞赛平台,主要面向大学生和编程爱好者...
在这种情况下,"ai3717"可能是C++、Java或其他编程语言的源代码文件,包含了作者对POJ3717问题的解决方案。 由于没有给出具体的题目内容和代码,我们无法深入讨论解题策略或算法实现。不过,一般来说,解决POJ上的...
根据【压缩包子文件的文件名称列表】:“北大题”,我们可以推测这个压缩包内包含的是一系列与北京大学POJ题库相关的题目解法代码。每个文件可能对应一个具体的题目,文件名可能是题目的编号或者题目描述的一部分。 ...
北京大学的POJ题目解题代码集合是一份宝贵的资源,它涵盖了ACM(国际大学生程序设计竞赛)中的许多问题,旨在帮助学生和编程爱好者提升算法理解与编程技能。POJ(Problem Set for Online Judges)是中国最早的在线...
2. "POJ1010-STAMPS.doc":这是一个文档文件,很可能包含了对问题的详细解释、解题思路、算法流程图、时间复杂度分析等内容,对于学习和理解这个问题的解法非常有帮助。 综合以上信息,我们可以推断,"POJ1010-...
【压缩包子文件的文件名称列表】中,"POJ2531-Network Saboteur.cpp"是用C++编写的源代码文件,包含了实现解题逻辑的程序;"POJ2531-Network Saboteur.doc"可能是一个文档文件,详细解释了解题思路、算法描述或者...
"POJ 1000-1200大部分资源代码"是一个专门为初学者准备的宝藏库,其中包含了C++和JAVA两种编程语言的源码。POJ,全称是Programming Online Judge,是一个知名的在线编程竞赛平台,它为程序员提供了丰富的编程题目,...
【压缩包子文件的文件名称列表】中,"POJ3080-Blue Jeans.cpp" 是提交给POJ平台的AC代码,可能包含了上述的动态规划解法,使用C++语言实现。"POJ3080-Blue Jeans.doc" 可能是解题报告文档,详细解释了解题过程和思路...
POJ是一个以C、C++和Java为主要语言的在线编程竞赛平台,它提供了各种算法和逻辑思维的练习题目,旨在提升程序员的编程能力和解决问题的能力。 描述中的“网上收集”表明这个压缩包里的代码是从网络上搜集而来,...
首先,我们需要理解POJ(北大在线评测系统)是一个供程序员练习和提交代码的平台,主要支持C、C++和Java语言。它提供各种不同难度级别的编程题目,帮助用户提升算法和编程能力。 题目“Check the difficulty of ...
ACM竞赛旨在提升大学生的算法设计和编程能力,因此题目的难度和复杂性较高,涉及的编程语言通常包括C、C++、Java等。这个描述中的"来源网络"和"自己整理一部分"说明了题目的收集方式,既包括网络上公开的资源,也有...
【压缩包子文件的文件名称列表】:POJ1338 这个文件可能是包含解题代码的源文件,通常使用的编程语言可能有C++、Java、Python等。解题代码会清晰地展示如何根据题目要求构建算法,实现数据结构,以及如何优化时间...
它支持多种编程语言,如C、C++、Java等,参赛者可以提交代码并立即获取运行结果和评测报告,有利于选手自我检验和提高。 三、解题报告的重要性 解题报告是ACM竞赛学习中的重要参考资料。它通常包含以下几个部分: 1...
5. 思路拓展:讨论可能的优化方法,或者对比不同解法的优缺点,帮助读者深化对问题本质的理解。 通过阅读《北大ACM题解》,你可以学习到如何分析问题,选择合适的算法,以及编写高效的代码。这将对你在ACM竞赛中的...
在"poj.rar"这个压缩包中,包含的是用户完成的POJ题目源代码,可能是用C、C++或Java等编程语言编写的。 【描述】"我最近做的几个poj题目源代码,可能比较简单" 暗示了这些代码是作者近期解决的一些基础或入门级别的...
【压缩包子文件的文件名称列表】中的"POJ1083-Moving Tables.cpp"是C++语言编写的源代码文件,包含了解决该问题的算法实现。".cpp"扩展名表明这是一段C++代码,可能使用了STL(Standard Template Library)等C++特性...
1. "POJ1716-Integer Intervals【Difference Constraints】.cpp":这可能是基于差分约束系统理论的C++代码实现,它可能采用了动态规划或者线性规划的方法来解决问题。 2. "POJ1716-Integer Intervals【Greed】.cpp...
4. **编程实践**:通过"poj_3310.txt"中的代码,我们可以看到问题的代码实现,这可能涉及C++、Java或Python等常见编程语言,学习如何将算法转化为实际的程序。 5. **代码优化**:作者可能会分享代码优化的技巧,...