poj1013

题目描述: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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值