正文

Zju 1184 Counterfeit Dollar2006-09-15 17:49:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/cruxd/18550.html

分享到:

2068160 2006-09-15 17:18:10 Accepted 1184 C++ 00:00.00 844K St.Crux

    这是一个古老的题目,12枚硬币称3次,求出其中那枚轻或重的硬币。

    当然,这道题比求解法简单多了,只需求证明。而我们知道,证明一样物体的存在,只需要把与其对立面的物体从物理层面乃至精神层面完全地、不留遗迹地消灭,这点在人类文明史中得到了最有力的支持......因此,最简单的办法是枚举24种情况,然后一一搜索,不满足者剔除即可。但显然这比较笨拙。

    有没有简单一点的办法——假如不是12枚,而是12亿枚?好吧,同样是剔除,我们可以从判断语句入手。

    比如 ABCD EFGH even 我们知道了这八枚都是even的。

    又比如 ABCI EFJK up 我们知道了ABCI里必然有一枚是heavy的,而EFJK必然有一枚light。因此ABCI就是heavy的嫌疑对象,反之亦然。这是可能性。

    从上面的语句中,我们还能得到隐含的条件:DGHL必然是even的。这是必然性。

    所以,只要把不满足必然性的可能性剔除就OK了。

    至于这个问题的解法,大致是用到二分,具体怎么写还有待研究。

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
using namespace std;

int n, b[12], l0, l1, c[12];
string s0, s1, s2;

void proc();
void print();

int main()
{
 //freopen("in.txt", "r", stdin);
 cin >> n;
 int i, k;
 for(i = 0; i < n; i ++)
 {
  memset(b, 0, sizeof(b));
  for(k = 0; k < 3; k ++)
  {
   cin >> s0 >> s1 >> s2;
   l0 = s0.size(), l1 = s1.size();
   proc();
  }
  print();
 }
 return 0;
}

void proc()
{
 int j, t;
 //cout << s0 << " " <<  s1 << " " <<  s2 << endl;
 memset(c, 0, sizeof(c));
 if(s2 == "even") //两边相等
 {
  for(j = 0; j < l0; j ++)
  {
   t = s0[j] - 'A'; 
   if(b[t] == 2) continue;
   b[t] = 2;  //2代表相等
  }
  for(j = 0; j < l1; j ++)
  {
   t = s1[j] - 'A';
   if(b[t] == 2) continue;
   b[t] = 2; 
  } 
 }
 else if(s2 == "up")  //左边重
 {
  for(j = 0; j < l0; j ++)
  {
   t = s0[j] - 'A';
   c[t] = 1;
   if(b[t] == 2) continue;
   if(b[t] == 1) b[t] = 2;  //有1存在说明这是标准重量
   if(!b[t]) b[t] = 3; //3代表重的可能性   
  }  
  for(j = 0; j < l1; j ++)
  {
   t = s1[j] - 'A';
   c[t] = 1;
   if(b[t] == 2) continue;
   if(b[t] == 3) b[t] = 2;  //有3存在说明这是标准重量
   if(!b[t]) b[t] = 1; //1代表轻的可能性   
  } 
  for(j = 0; j < 12; j ++)
  {
   if(!c[j])
   {
    t = j;
    if(b[t] == 2) continue;
    b[t] = 2;
   }
  }
 }
 else if(s2 == "down")  //右边重
 {
  for(j = 0; j < l0; j ++)
  {
   t = s0[j] - 'A';
   c[t] = 1;
   if(b[t] == 2) continue;
   if(b[t] == 3) b[t] = 2;  
   if(!b[t]) b[t] = 1;    
  }  
  for(j = 0; j < l1; j ++)
  {
   t = s1[j] - 'A';
   c[t] = 1;
   if(b[t] == 2) continue;
   if(b[t] == 1) b[t] = 2;  
   if(!b[t]) b[t] = 3;    
  } 
  for(j = 0; j < 12; j ++)
  {
   if(!c[j])
   {
    t = j;
    if(b[t] == 2) continue;
    b[t] = 2;
   }
  }
 }
 //print();
}

void print()
{
 int i;
 for(i = 0; i < 12; i ++)
 {
  if(b[i] == 2) continue;
  if(b[i] == 1)
  {
   printf("%c is the counterfeit coin and it is light.\n", i + 'A');
  }
  if(b[i] == 3)
  {
   printf("%c is the counterfeit coin and it is heavy.\n", i + 'A');
  }
 }
}


 

阅读(3775) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册