Counterfeit Dollar

181 篇文章 0 订阅
173 篇文章 3 订阅

Link:http://acm.fzu.edu.cn/problem.php?pid=1003


Problem 1003 Counterfeit Dollar

Accept: 1107    Submit: 4860
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

Sally Jones has a dozen Voyageur silver dollars. However, only eleven of the coins are true silver dollars; one coin is counterfeit even though its color and size make it indistinguishable from the real silver dollars. The counterfeit coin has a different weight from the other coins but Sally does not know if it is heavier or lighter than the real coins.

Happily, Sally has a friend who loans her a very accurate balance scale. The friend will permit Sally three weighings to find the counterfeit coin. For instance, if Sally weighs two coins against each other and the scales balance then she knows these two coins are true. Now if Sally weighs one of the true coins against a third coin and the scales do not balance then Sally knows the third coin is counterfeit and she can tell whether it is light or heavy depending on whether the balance on which it is placed goes up or down, respectively.

By choosing her weighings carefully, Sally is able to ensure that she will find the counterfeit coin with exactly three weighings.


 Input

The first line of input is an integer n (n > 0) specifying the number of cases to follow. Each case consists of three lines of input, one for each weighing. Sally has identified each of the coins with the letters A-L. Information on a weighing will be given by two strings of letters and then one of the words ``up'', ``down'', or ``even''. The first string of letters will represent the coins on the left balance; the second string, the coins on the right balance. (Sally will always place the same number of coins on the right balance as on the left balance.) The word in the third position will tell whether the right side of the balance goes up, down, or remains even.

 Output

For each case, the output will identify the counterfeit coin by its letter and tell whether it is heavy or light. The solution will always be uniquely determined.

 Sample Input

1ABCD EFGH evenABCI EFJK upABIJ EFGH even

 Sample Output

K is the counterfeit coin and it is light.

分析:假币问题的源码,通过三次天平比较,从12枚外形一致的金币中找出唯一的假币并判断假币重量高于(低于)真币。


//题目大概意思
//有12个硬币,其中一个不正常,现在要求通过3次测量,找出这个硬币,并且确定这个硬币是比较重的还是比较轻的
/*
**状态:
**0.正常 1.重 2.不确定 -1.轻


**隐含条件:
**1.两边的硬币个数要相等
**2.右边的比较轻时,可能要找的硬币在右边,且比较轻;或者在左边,且比较重
**3.当出现不相等的情况时,剩余的硬币都是正常的
*/

AC code:

#include <stdio.h>
#include <string.h>

#define OneSideMax 6 //一边硬币的最大数 
#define CoinMax 12  //最大的硬币个数
#define StatusLen 4 //up,down,even的最大长度

char left[OneSideMax+1]; //左边硬币
char right[OneSideMax+1];
char status[StatusLen+1];
int coin[CoinMax+1]; //对应硬币的状态

void MarkNormal(const char *str,int len)
{
 int i;
 for(i=0;i<len;i++)
  coin[str[i]-'A']=0;
}

void MarkLight(const char *str,int len)
{
 int i;
 for(i=0;i<len;i++)
 {
  if(2==coin[str[i]-'A'])  //硬币状态不确定
   coin[str[i]-'A']=-1;
  if(1==coin[str[i]-'A']) //硬币以前可能比较重,现在比较轻,所以只能硬币是正常的
   coin[str[i]-'A']=0;
 }
}

void MarkHeavy(const char *str,int len)
{
 int i;
 for(i=0;i<len;i++)
 {
  if(2==coin[str[i]-'A'])
   coin[str[i]-'A']=1;
  if(-1==coin[str[i]-'A'])
   coin[str[i]-'A']=0;
 }
}

void MarkRemainNormal(const char *str1,const char *str2,int len)
{
 int i;
 int temp[CoinMax+1];
 for(i=0;i<len;i++)
 {
  temp[str1[i]-'A']=1;
  temp[str2[i]-'A']=1;
 }
 for(i=0;i<CoinMax;i++)
 {
  if(1!=temp[i])
   coin[i]=0;
 }
}

int main()
{
 int t;
 int len;
 int i;
 scanf("%d",&t);
 while(t--)
 {
  for(i=0;i<CoinMax;i++)
   coin[i]=2;
  for(i=0;i<3;i++)
  {
   memset(left,'\0',sizeof(left));
   memset(right,'\0',sizeof(right));
   memset(status,'\0',sizeof(status));
   scanf("%s%s%s",left,right,status);
   len = strlen(left);//左边的等于右边
   if('e'==status[0])
   {
    MarkNormal(left,len);
    MarkNormal(right,len);
   }
   else if('u'==status[0])  //右边轻
   {
    MarkLight(right,len);
    MarkHeavy(left,len);
    MarkRemainNormal(left,right,len);
   }
   else                     //右边重
   {
    MarkLight(left,len);
    MarkHeavy(right,len);
    MarkRemainNormal(left,right,len);
   }
  }
  for(i=0;i<CoinMax;i++)
   if(coin[i]!=0)
    break;
  if(-1==coin[i])
  {
   printf("%c is the counterfeit coin and it is light.\n",i+'A');
  }
  else
  {
   printf("%c is the counterfeit coin and it is heavy.\n",i+'A');
  }
 }

 return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值