POJ1013称硬币

来源:互联网 发布:淘宝自动浏览收藏软件 编辑:程序博客网 时间:2024/06/08 18:52
莎莉琼斯有十几条Voyageur银币。然而,只有十一个硬币是真正的银币; 一枚硬币是伪造的,尽管它的颜色和尺寸使其与真正的银币无法区分。假币与其他硬币的重量不同,但Sally不知道它比真实的硬币更重或更轻。 
令人高兴的是,Sally有一个朋友,她给她一个非常准确的平衡表。朋友将允许Sally三个称重找到假币。例如,如果Sally将两个硬币相互重叠,并且秤平衡,那么她知道这两个硬币是正确的。现在如果萨莉重了 
其中一枚针对第三枚硬币的金币和鳞片不平衡,Sally知道第三枚硬币是假冒的,她可以分辨其是否轻或重,取决于它放置的天平是否上升或下降。 
通过仔细选择她的称重,Sally能够确保她会找到三个称重的假币。

输入

第一行输入是一个整数n(n> 0),指定要跟随的个案数。每个案例由三行输入组成,一组用于每个称重。Sally已经用字母A-L识别出每个硬币。关于称重的信息将由两串字母给出,然后是“up”,“down”或“even”之一。第一串字母将代表左边平衡上的硬币; 第二个弦,硬币在右边平衡。(Sally将总是将相同数量的硬币放在与左侧平衡上相同的平衡上)。第三个位置的单词会告诉您平衡的右侧是否上升,下降或保持均匀。

产量

对于每种情况,输出将通过其字母识别伪币,并判断是否重或轻。解决方案将永远是唯一确定的。

样品输入

1 ABCD EFGH evenABCI EFJK upABIJ EFGH down

样品输出

K是假币,很轻。 
解题思路:这道题是典型的枚举题,根据输入的情况来假设假的硬币是重还是轻,然后从A遍历到L,利用假设找到符合假设情况
的例。

共三种状态:

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

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

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

 

注意题目的字眼:

1、  有且仅有1枚假币

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

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

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

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

代码如下:
#include<stdio.h>#include<string.h>char left[3][7],right[3][7],res[3][7];int searchBad(char c,int x)//x表示轻重参数,1为轻,2为重 {int i;char *pl,*pr;for(i = 0;i < 3;i ++){if(x == 1){pl = left[i];pr = right[i];}else{pr = left[i];pl = right[i];}switch(res[i][0]){case 'u':if(strchr(pr,c) == NULL)return 0;break;case 'e':if(strchr(pr,c) || strchr(pl,c))return 0;break;case 'd':if(strchr(pl,c) == NULL)return 0;break;} }  return 1;}int main(){int n,i;char c;scanf("%d",&n);while(n --){for(i = 0;i < 3;i ++)scanf("%s%s%s",left[i],right[i],res[i]);for(c = 'A';c <= 'L';c ++){if(searchBad(c,1) == 1){printf("假币%c是轻的\n",c);break;}else if(searchBad(c,2) == 1){printf("假币%c是重的\n",c);break;}}}return 0;}