poj1013

来源:互联网 发布:嘉艺发型设计软件 编辑:程序博客网 时间:2024/05/17 09:36

题目描述:12个金币中有一个是假币,假币的大小颜色都和真的一样,只有重量不一样,但是有可能比真的轻,也有可能重,现在要通过称重找出那个假的。
输入格式:第一行一个整数n,表示有n组数据,每组数组有3行输入,每行由被2个空格隔开的三个字符串组成,表示一次称重的结果,前字符串由A-L的大写英文字母组成,分别表示天平左边和右边分别放的金币编号。第三个字符串有三种情况”even”,”up”,”down”.分别表示平衡,左边轻,右边轻。
输出格式:每组数据输出一行,表示哪个金币是假币,并输出是比真币重还是轻。例如:K is the counterfeit coin and it is light.
数据保证:并没有任何保证,如果只有12个币不算的话、

解题思路:

  • 首先明确的是,如果是even,则此次称重的所有金币(左右两边的)都是真的。
  • 其次,又在重的一边出现过又在轻的一边出现过的金币是真的。(即在两次称重中处于不同的状态的金币是真的)
  • 最后,在重的一边或轻的一边次数最多的是假币(这个我也不知道为什么,我按照前面两点写出来的算法有错误,然后对着数据看了一下,假币up的次数多,所以。。。)

PS:最近两道题目的题意都是我自己看懂的。没看翻译,只是想好好练习我的英语,似乎效果还可以,要坚持下去!

#include <cstdio>#define  abs(a) ({ (a)>0?(a):-(a); })int main(int argc, char const *argv[]){    int n;    char s1[3][100], s2[3][100], s3[3][100];    for(scanf("%d", &n); n--;){        int  u[20]={0}, d[20]={0};        bool e[20]={false};        for(int i=0; i<3; ++i){            scanf("%s%s%s", s1[i], s2[i], s3[i]);            for(int j=0; s1[i][j] && s2[i][j]; ++j){                switch(s3[i][0]){                    case 'e':                        e[s1[i][j]-'A']=true;                        e[s2[i][j]-'A']=true;                        break;                    case 'u':                        u[s1[i][j]-'A']++;                        d[s2[i][j]-'A']++;                        break;                    case 'd':                        d[s1[i][j]-'A']++;                        u[s2[i][j]-'A']++;                        break;                    default:                        break;                }            }        }        int max=-1, ans=-1;        for(int i=0; i<12; ++i){            if(u[i]&&d[i]) { e[i]=true; }            if(e[i]) { continue; }            int tmp=abs(u[i]-d[i]);            if(tmp>max){ max=tmp; ans=i; }        }        printf("%c is the counterfeit coin and it is %s.\n", 'A'+ans, u[ans]<d[ans]?"light":"heavy");    }    return 0;}
0 0
原创粉丝点击