首页 > 试题广场 >

Counterfeit Dollar

[编程题]Counterfeit Dollar
  • 热度指数:2413 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
    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.

输入描述:
   . 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.


输出描述:
    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.
示例1

输入

1
ABCD EFGH even 
ABCI EFJK up 
ABIJ EFGH even 

输出

K is the counterfeit coin and it is light.
//假设假币是轻的。even则在称量的都正常,down则右边的都正常(其他都正常),up则左边都正常(其他都正常)。把结果记录在light[]中,正常的为true。
//假设假币是重的,操作方法同上,把结果记录在heavy[]中,正常的为true。
//轻或重只可能有一种情况,遍历light[]和heavy[],只有1个为false的就是结果。
#include<string>
#include<iostream>
using namespace std;

bool light[13],heavy[13];

void lightTrue(string str){//如果假币是轻的,str中为正常
    int len=str.size();
    for(int i=0;i<len;++i){
        light[str[i]-'A']=true;
    }
}

void heavyTrue(string str){//如果假币是重的,str中为正常
      int len=str.size();
    for(int i=0;i<len;++i){
        heavy[str[i]-'A']=true;
    }
}

void bothTrue(string str){//无论假币轻重,str中为正常
    int len=str.size();
    for(int i=0;i<len;++i){
        heavy[str[i]-'A']=true;
        light[str[i]-'A']=true;
    }
}

int main(){
    string left,right,other,decide;
    int i,j,k,t;
    while(cin>>left>>right>>decide){//连续读入数据
        for(i=0;i<13;++i){light[i]=false;heavy[i]=false;}//初始化
        int count=2;
        while(1){
            --count;
            other="";
            for(char a='A';a<='L';++a){//此次未称量的硬币
                if(left.find(a)==string::npos&&right.find(a)==string::npos){other+=a;}
            }
            if(decide=="even"){
                bothTrue(left);bothTrue(right);
            }
            else if(decide=="up"){
                bothTrue(other);lightTrue(right);heavyTrue(left);
            }
            else{bothTrue(other);lightTrue(left);heavyTrue(right);}
            if(count<0){break;}
            cin>>left>>right>>decide;
            }
        int light_count=0,heavy_count=0,light_loc=0,heavy_loc=0;
        for(i=0;i<12;++i){//统计light和heavy中false的数量和位置
            if(light[i]==false){++light_count;light_loc=i;}
            if(heavy[i]==false){++heavy_count;heavy_loc=i;}
        }
            //输出结果,注意light中为false,说明是heavy,反之亦然。
        if(light_count==1){printf("%c is the counterfeit coin and it is heavy.",'A'+light_loc);}
        if(heavy_count==1){printf("%c is the counterfeit coin and it is light.",'A'+heavy_loc);}
    }
    
    return 0;
}

编辑于 2019-02-21 21:03:37 回复(1)
自己暴力了一下,提供我的思路:
1.输入的三行,两种情况---左右相等;左右不等(交换天平两端,只剩下大于这种情况) 
2.一共三行,分类讨论:相等的有m==0,1,2;(3不会出现,否则无法判断假币的重量) 3.m==0时,
3.1三行数据中 左侧的共有字符;
3.2 或者右侧共有字符(二者出现其一),即为假币,左侧为重,右侧为轻;
4.m==1||m==2时, 
4.1 记录天平相等时,两侧的字符;
4.2 消除不等天平两侧的真币 
4.3此时,天平不等时的共有唯一字符(左 右分别记录),即所求,左重右轻 
5.总体来说,排除平衡天平两端的字符;在剩余字符,从不平衡的天平两侧分别找到共有字符,即为所求

编辑于 2020-03-22 09:56:07 回复(1)
#include <cstdio>
#include <cstring>
using namespace std;

bool heavy[12];
bool normal[12];
bool light[12];
bool mark[12];
char str1[21];
char str2[21];
char str3[21];

void balance() {
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    if(strcmp(str3, "even") == 0) {
        for(int i = 0; i < len1; i++) {
            normal[str1[i]-'A'] = true;
        }
        for(int i = 0; i < len2; i++) {
            normal[str2[i]-'A'] = true;
        }
    } else if(strcmp(str3, "up") == 0) {
        for(int i = 0; i < 12; i++) {
            mark[i] = false;
        }
        for(int i = 0; i < len1; i++) {
            heavy[str1[i]-'A'] = true;
            mark[str1[i]-'A'] = true;
        }
        for(int i = 0; i < len2; i++) {
            light[str2[i]-'A'] = true;
            mark[str2[i]-'A'] = true;
        }
        for(int i = 0; i < 12; i++) {
            if(!mark[i]) normal[i] = true;
        }
    } else if(strcmp(str3, "down") == 0) {
        for(int i = 0; i < 12; i++) {
            mark[i] = false;
        }
        for(int i = 0; i < len1; i++) {
            light[str1[i]-'A'] = true;
            mark[str1[i]-'A'] = true;
        }
        for(int i = 0; i < len2; i++) {
            heavy[str2[i]-'A'] = true;
            mark[str2[i]-'A'] = true;
        }
        for(int i = 0; i < 12; i++) {
            if(!mark[i]) normal[i] = true;
        }
    }
}

int main() {
    while(scanf("%s%s%s", str1, str2, str3) == 3) {
        for(int i = 0; i < 12; i++) {
            heavy[i] = false;
            normal[i] = false;
            light[i] = false;
        }
        balance();
        scanf("%s%s%s", str1, str2, str3);
        balance();
        scanf("%s%s%s", str1, str2, str3);
        balance();
        for(int i = 0; i < 12; i++) {
            if(!(normal[i] || (heavy[i] && light[i]))) {
                printf("%c is the counterfeit coin and it is ", 'A' + i);
                if(light[i]) printf("light.\n");
                else printf("heavy.\n");
            }
        }
    }

    return 0;
}

发表于 2018-02-09 11:08:12 回复(0)
比false coin那道题还简单一些,思路是一样的
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n=12,k=3,flag[12];
    string ch,left,right;
    map<char,int> m;
    for(int i=0;i<n;i++)m[i+'A']=1;
    for(int i=0;i<k;i++){
        memset(flag,0,sizeof(flag));
        cin>>left>>right>>ch;
        if(ch=="even"){
            for(auto i:left)m[i]=2;
            for(auto i:right)m[i]=2;
        }
        if(ch=="down"){
            for(auto i:left)m[i]=(m[i]!=1&&m[i]!=3)?2:3,flag[i-'A']=1;
            for(auto i:right)m[i]=(m[i]!=1&&m[i]!=4)?2:4,flag[i-'A']=1;
            for(int i=0;i<12;i++)if(!flag[i])m[i+'A']=2;
        }
        if(ch=="up"){
            for(auto i:left)m[i]=(m[i]!=1&&m[i]!=4)?2:4,flag[i-'A']=1;
            for(auto i:right)m[i]=(m[i]!=1&&m[i]!=3)?2:3,flag[i-'A']=1;
            for(int i=0;i<12;i++)if(!flag[i])m[i+'A']=2;
        }
    }
    for(auto iter:m){
        if(iter.second==3)cout<<iter.first<<" is the counterfeit coin and it is light."<<endl;
        else if(iter.second==4)cout<<iter.first<<" is the counterfeit coin and it is heavy."<<endl;
    }
    return 0;
}


发表于 2020-03-28 19:50:52 回复(0)
啥头像
跟“false coin”那题思想类似
    每个硬币三种状态:0(标准重量) 1(大于等于标准重量) -1(小于等于标准重量)
    用2来初始化。
    又因为只有一个坏的硬币
    当A组硬币   >     B组硬币时, 则A组硬币 大于等于标准重量,   B组硬币 小于等于标准重量,且不属于A组、B组的硬币都为标准重量
    当A组硬币   <    B组硬币时, 则B组硬币 大于等于标准重量,  A 组硬币 小于等于标准重量,且不属于A组、B组的硬币都为标准重量
上述两种情况要处理一种情况,当某个硬币既大于等于标准重量又 小于等于标准重量,则这个硬币等于标准重量
    当A组硬币   =    B组硬币时, 则属于A组、B组的硬币都为标准重量

    判定:不为0的那个硬币为坏的,大于0表示重了,小于0表示轻了

#!/usr/bin/python
#-*- coding:utf-8 -*-

#Author: Ben

dollars = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']

def char2idx(ch):   
    return ord(ch)-65

def idx2char(idx):
    return chr(65+idx)

def evenCase(rlt, left, right):
    for ch in left:
        rlt[char2idx(ch)] = 0
    for ch in right:
        rlt[char2idx(ch)] = 0

def upCase(rlt, left, right):
    for ch in dollars:
        if ch not in left and ch not in right:
            rlt[char2idx(ch)] = 0
    for ch in left:
        idx = char2idx(ch)
        if rlt[idx] == 2:
            rlt[idx] == 1
        elif rlt[idx] < 0:
            rlt[idx] = 0
    for ch in right:
        idx = char2idx(ch)
        if rlt[idx] == 2:
            rlt[idx] = -1
        elif rlt[idx] == 1:
            rlt[idx] = 0

def downCase(rlt, left, right):
    for ch in dollars:
        if ch not in left and ch not in right:
            rlt[char2idx(ch)] = 0
    for ch in left:
        idx = char2idx(ch)
        if rlt[idx] == 2:
            rlt[idx] = -1
        elif rlt[idx] == 1:
            rlt[idx] = 0
    for ch in right:
        idx = char2idx(ch)
        if rlt[idx] == 2:
            rlt[idx] = 1
        elif rlt[idx] < 0:
            rlt[idx] = 0

def judge(rlt):
    val = 0; idx = 0
    for i,j in enumerate(rlt):
        if j != 0:
            idx, val = i, j
    return idx2char(idx), val

while True:
    try:
        N = input()
        while N:
            N -= 1
            rlt = [2]*12
            for i in range(3):
                left, right, sym = raw_input().strip().split()
                if sym == 'even':
                    evenCase(rlt, left, right)
                elif sym == 'up':
                    upCase(rlt, left, right)
                else:
                    downCase(rlt, left, right)
            ch, val = judge(rlt)
            if val == -1:
                val = 'light'
            else:
                val = 'heavy'
            print '%s is the counterfeit coin and it is %s.' % (ch,val)
    except:
        break


编辑于 2016-04-03 17:14:38 回复(0)
/*
题目翻译:
描述:
萨莉·琼斯有一打旅行者银元。然而,只有十一枚硬币是真正的银元;
一枚硬币是伪造的,尽管它的颜色和大小使它与真正的银币无法区分。
这枚假币的重量与其他硬币不同,但Sally不知道它是比真硬币重还是轻。
令人高兴的是,萨莉有一个朋友借给她一个非常准确的天平。
这位朋友将允许萨莉称重三次才能找到那枚假币。
例如,如果Sally称两枚硬币的重量,天平保持平衡,那么她就知道这两枚硬币是真的。
现在,如果Sally将其中一枚真硬币与第三枚硬币称重,但天平不平衡,
那么Sally就知道第三枚是伪造的,
她可以根据放置硬币的天平是向上还是向下来判断它是轻是重。
通过仔细选择秤,Sally能够确保她能准确地找到三次秤的假币。
输入描述:
每个箱子由三行输入组成,每个称重一行。
萨莉用字母A-L辨认出每一枚硬币。
称重信息将由两个字母串给出,
然后是其中一个单词“向上”(up)、“向下”(down)或“平衡”(even)。
第一个字母串将代表左边天平上的硬币;第二个字符串代表右边天平上的硬币。
(Sally总是把相同数量的硬币放在左右边的天平上。)
第三个位置的单词会告诉你天平的右边是向上、向下还是保持平衡。
输出描述:
对于每种情况,输出都会通过其字母来识别假币,并判断它是重还是轻。
解决方案总是唯一确定的。
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;

enum Status {   //硬币状态
    TRUE, LIGHT, HEAVY, UNKNOWN //真币,“疑似”偏轻,“疑似”偏重,不确定真假
};

int main() {
    vector<Status>coins('L' + 1);   //数组仅'A'~'L'位有效
    vector<int>weight('L' + 1);     //硬币的“重量”
    for (int i = 'A'; i <= 'L'; i++) {
        coins[i] = UNKNOWN;
        weight[i] = 0;
    }
    for (int i = 0; i < 3; i++) {
        string left, right, info;
        cin >> left >> right >> info;
        if (info == "even") {   //平衡,则全部为真币
            for (const auto& ch : left) {
                coins[ch] = TRUE;
            }
            for (const auto& ch : right) {
                coins[ch] = TRUE;
            }
        } else if (info == "up") {  //右边高
            for (const auto& ch : left) {
                if (coins[ch] != TRUE) {
                    coins[ch] = HEAVY;  //疑似偏重
                    weight[ch]++;
                }
            }
            for (const auto& ch : right) {
                if (coins[ch] != TRUE) {
                    coins[ch] = LIGHT;  //疑似偏轻
                    weight[ch]--;
                }
            }
        } else if (info == "down") {  //右边低
            for (const auto& ch : left) {
                if (coins[ch] != TRUE) {
                    coins[ch] = LIGHT;  //疑似偏轻
                    weight[ch]--;
                }
            }
            for (const auto& ch : right) {
                if (coins[ch] != TRUE) {
                    coins[ch] = HEAVY;  //疑似偏重
                    weight[ch]++;
                }
            }
        }
    }
    int max_weight = 0, min_weight = 0; //“重量”的最大值、最小值
    char heaviest_coin, lightest_coin;  //“最重”和“最轻”的硬币
    for (int i = 'A'; i <= 'L'; i++) {
        if (coins[i] == HEAVY) {
            if (max_weight < weight[i]) {
                max_weight = weight[i];
                heaviest_coin = i;
            }
        } else if (coins[i] == LIGHT) {
            if (min_weight > weight[i]) {
                min_weight = weight[i];
                lightest_coin = i;
            }
        }
    }
    if (abs(max_weight) > abs(min_weight)) {
        cout << heaviest_coin << " is the counterfeit coin and it is heavy."
             << endl;
    } else {
        cout << lightest_coin << " is the counterfeit coin and it is light."
             << endl;
    }
    return 0;
}

编辑于 2024-01-31 20:35:42 回复(0)
这个比之前那个也是称硬币的要简单,这个是能保证三次能确定假币的
所以还是使用模拟假设枚举的方式,假设重,假设轻,只要匹配成功一次,那就能确定就是它,其他的肯定不能匹配成功
#include <cstdio>
#include <iostream>
#include <string>
#include <type_traits>
using namespace std;

int iweight[12];
string sresult[3],sleft[3],sright[3];

bool match(){
    for(int i=0;i<3;i++){
        int ileft=0,iright=0;
        for(int j=0;j<sleft[i].size();j++){
            ileft+=iweight[sleft[i][j]-'A'];
            iright+=iweight[sright[i][j]-'A'];
        }
        if(ileft>iright&&sresult[i]=="up"){
            continue;
        }else if(ileft==iright&&sresult[i]=="even"){
            continue;
        }else if(ileft<iright&&sresult[i]=="down"){
            continue;
        }else{
            return false;
        }
    }
    return true;
}

int main() {
    int caseNum=1;
    //cin>>caseNum;
    while(caseNum--){
        for(int i=0;i<3;i++){
            cin>>sleft[i]>>sright[i]>>sresult[i];
        }
        for(int i=0;i<12;i++){
            iweight[i]=2;
        }
        for(int i=0;i<12;i++){
            iweight[i]=1;
            if(match()){
                printf("%c is the counterfeit coin and it is light.\n",i+'A');
                break;
            }
            iweight[i]=3;
            if(match()){
                printf("%c is the counterfeit coin and it is heavy.\n",i+'A');
                break;
            }
            iweight[i]=2;
        }
    }
}

发表于 2023-02-13 11:22:12 回复(0)
/*初始化为全0, 并维护一个访问数组,判定为even将其访问数组为已访问*/
//up: 右边减一, 左边加一
//down: 右边加一, 左边减一
//even: 左右设为0, 访问数组置1

#include <bits/stdc++.h>

using namespace std;

const int maxn = 12;

int d[maxn];
bool v[maxn];

int main(){
    fill(d, d+maxn, 0);
    fill(v, v+maxn, false);
    for(int l=0; l<3; l++){
        string s;
        getline(cin, s);
        s.push_back(' ');
        stringstream ss(s);
        string temp;
        vector<string> strs;
        while(getline(ss, temp, ' ')){
            strs.push_back(temp);
        }
        if(strs[2]=="even"){
            for(int i=0; i<strs[0].size(); i++){
                d[strs[0][i]-'A'] = 0;
                v[strs[0][i]-'A'] = true;
            }
            for(int i=0; i<strs[1].size(); i++){
                d[strs[0][i]-'A'] = 0;
                v[strs[1][i]-'A'] = true;
            }
        }
        else if(strs[2]=="up"){
            for(int i=0; i<strs[0].size(); i++){
                if(v[strs[0][i]-'A'] == false){
                    d[strs[0][i]-'A'] += 1;
                }
            }
            for(int i=0; i<strs[1].size(); i++){
                if(v[strs[1][i]-'A'] == false){
                    d[strs[1][i]-'A'] -= 1;
                }
            }
        }
        else if(strs[2]=="down"){
            for(int i=0; i<strs[0].size(); i++){
                if(v[strs[0][i]-'A'] == false){
                    d[strs[0][i]-'A'] -= 1;
                }
            }
            for(int i=0; i<strs[1].size(); i++){
                if(v[strs[1][i]-'A'] == false){
                    d[strs[1][i]-'A'] += 1;
                }
            }
        }
    }
    int minv = INT_MAX, maxv = INT_MIN;
    int minindex = 0, maxindex = 0;
    for(int i=0; i<12; i++){
        if(d[i]<minv&&v[i]==false){
            minv = d[i]; minindex = i;
        }
        if(d[i]>maxv&&v[i]==false){
            maxv = d[i]; maxindex = i;
        }
    }
    if(abs(minv)<abs(maxv)){
        printf("%c is the counterfeit coin and it is heavy.\n", 'A' + maxindex);
    }
    if(abs(minv)>abs(maxv)){
        printf("%c is the counterfeit coin and it is light.\n", 'A' + minindex);
    }
    return 0;
}



发表于 2021-02-15 11:37:15 回复(0)
#include<bits/stdc++.h>
using namespace std;
int main(){
    string left,right,ch;
    int flag[12];   //flag标记大于或小于另一个字符串的字符串内所有出现的字母
    map<char,int> m;
    for(int i=0;i<12;++i){
        m[i+'A']=1;
    }
    for(int j=0;j<3;++j){
        cin>>left>>right>>ch;
        fill(flag,flag+12,0);
        if(ch=="even"){
            for(int i=0;i<left.size();++i){
                m[left[i]]=2;
                m[right[i]]=2;
            }
        }
        else{
		if(ch=="up"){
            for(int i=0;i<left.size();++i){
                if(m[left[i]]!=2&&m[left[i]]!=3){
                    m[left[i]]=4;
                }else{
                    m[left[i]]=2;   
                }
                flag[left[i]-'A']=1;
            }
            for(int i=0;i<right.size();++i){
                if(m[right[i]]!=2&&m[right[i]]!=4){
                    m[right[i]]=3;
                }else{
                    m[right[i]]=2;
                }
                flag[right[i]-'A']=1;
            }
        }
        if(ch=="down"){
             for(int i=0;i<left.size();++i){
                if(m[left[i]]!=2&&m[left[i]]!=4){
                    m[left[i]]=3;
                }else{
                    m[left[i]]=2;   
                }
                flag[left[i]-'A']=1;
            }
            for(int i=0;i<right.size();++i){
                if(m[right[i]]!=2&&m[right[i]]!=3){
                    m[right[i]]=4;
                }else{
                    m[right[i]]=2;
                }
                flag[right[i]-'A']=1;
            }
        }
        for(int i=0;i<12;++i){
            if(flag[i]==0)
                m[i+'A']=2;
        }
        }
    }
    for(int i=0;i<12;++i){
        if(m[i+'A']==3)
        {
            printf("%c is the counterfeit coin and it is light.",i+'A');
            break;
        }
        if(m[i+'A']==4)
        {
            printf("%c is the counterfeit coin and it is heavy.",i+'A');
            break;
        }
    }
    return 0;
}

发表于 2020-04-23 21:01:08 回复(0)
#include <bits/stdc++.h>
using namespace std;
string leftk[3],rightk[3],result[3];
bool isLight(char ch,bool light){
	string lefttmp,righttmp;
	for(int i=0;i<3;i++){
		if(light){
			lefttmp.assign(leftk[i]);
			righttmp.assign(rightk[i]);
		}
		else {
			lefttmp=rightk[i];
			righttmp=leftk[i];
		}
		switch(result[i][0]){
			case 'u':
				if(righttmp.find(ch)==string::npos) return false;
				break;
			case 'e':
				if(righttmp.find(ch)!=string::npos||lefttmp.find(ch)!=string::npos)return false;
				break;
			case 'd':
				if(lefttmp.find(ch)==string::npos) return false;
				break;
		}
	}
	return true;
}
int main(){
	
	for(int i=0;i<3;i++) cin>>leftk[i]>>rightk[i]>>result[i];
	for(char ch='A';ch<='L';ch=(char)(ch+1)){
		if(isLight(ch,true)){
			cout<<ch<<" is the counterfeit coin and it is light."<<endl;
		}
		else if(isLight(ch,false)){
			cout<<ch<<" is the counterfeit coin and it is heavy."<<endl;
		}
		
	}
	return 0;
}

发表于 2020-03-29 12:54:53 回复(0)
参考了评论区大佬们的思路,代码比较冗长,有些地方暴力处理了
#include<iostream>
(720)#include<cstdio>
using namespace std;
/*
//假设假币是轻的。even则在称量的都正常,down则右边的都正常(其他都正常),up则左边都正常(其他都正常)。把结果记录在light[]中,正常的为true。
//假设假币是重的,操作方法同上,把结果记录在heavy[]中,正常的为true。
//只要不平衡,那么除天平上之外的硬币都是正常的 
//轻或重只可能有一种情况,遍历light[]和heavy[],只有1个为false的就是结果。
*/
struct Balance{
	string left;
	string right;
	string status;
}; 
Balance balance[3];
bool light[12];
bool heavy[12];
int main(){
	for(int i=0;i<12;i++){
		light[i]=false;
		heavy[i]=false;
	}
	for(int i=0;i<3;i++){
		cin>>balance[i].left>>balance[i].right>>balance[i].status;
	}
	for(int i=0;i<3;i++){
		if(balance[i].status=="even"){
			for(int j=0;j<balance[i].left.size();j++){
				light[balance[i].left[j]-'A']=true;
				heavy[balance[i].left[j]-'A']=true;
			}
			for(int j=0;j<balance[i].right.size();j++){
				light[balance[i].right[j]-'A']=true;
				heavy[balance[i].right[j]-'A']=true;
			}
		}else if(balance[i].status=="up"){
			for(int j=0;j<balance[i].left.size();j++){
				light[balance[i].left[j]-'A']=true;//假设假币轻,则左边的正常 (重的一方正常)
			}
			for(int j=0;j<balance[i].right.size();j++){
				heavy[balance[i].right[j]-'A']=true;//假设假币重,则右边的正常 
			}
			//这种情况容易漏,如果不平衡,那么除了天平上的硬币,其他的都正常
			for(int j=0;j<12;j++){
				bool flag=true;
				for(int k=0;k<balance[i].right.size();k++){
					if(j+'A'==balance[i].right[k]||j+'A'==balance[i].left[k]){
						flag=false;
					}
				}
				if(flag){
					light[j]=true;
					heavy[j]=true;
				}
			} 
		}else if(balance[i].status=="down"){
			for(int j=0;j<balance[i].right.size();j++){//假设轻 
				light[balance[i].right[j]-'A']=true;//重的右边正常 
			}
			for(int j=0;j<balance[i].left.size();j++){//假设重 
				heavy[balance[i].left[j]-'A']=true;//轻的左边正常 
			}
			//这种情况容易漏,如果不平衡,那么除了天平上的硬币,其他的都正常
			for(int j=0;j<12;j++){
				bool flag=true;
				for(int k=0;k<balance[i].right.size();k++){
					if(j+'A'==balance[i].right[k]||j+'A'==balance[i].left[k]){
						flag=false;
					}
				}
				if(flag){
					light[j]=true;
					heavy[j]=true;
				}
			} 
		}
	}
	int i=0;
	string status="";
	for(i=0;i<12;i++){
		if(light[i]==false&&heavy[i]==true||light[i]==true&&heavy[i]==false){
			if(light[i]==false&&heavy[i]==true){
				status="light";
			}else{
				status="heavy";
			}
			break;
		}
	}
	char c=(char)i+'A';
	cout<<c<<" is the counterfeit coin and it is "<<status<<"."<<endl;

	return 0;
}

发表于 2020-03-09 11:51:37 回复(0)
//***你告诉我A到L有多少个字母?11个?你是不是体育老师教的数学?
#include<iostream>
#include<string>
using namespace std;
int Transf(char x)
 {return x-'A';
 }
int main()
{int a[12]={};
int l[12]={};
int h[12]={};
bool c[12]={};
string flag;
int key=0;
int time=0;//计算天平失衡的次数
for(int i=0;i<3;i++)
 {string x,y,z;
 cin>>x>>y>>z;
 if(z=="even")
 {
 for(size_t i=0;i<x.size();i++)
   {a[Transf(x[i])]++;
   }
 for(size_t i=0;i<y.size();i++)
   {a[Transf(y[i])]++;
   }
 }
 else if(z=="up")
  {for(size_t i=0;i<x.size();i++)
   {h[Transf(x[i])]++;}
 for(size_t j=0;j<y.size();j++)
   {l[Transf(y[j])]--; }
    time++;
  }
 else if(z=="down")
  {for(size_t i=0;i<x.size();i++)
   {l[Transf(x[i])]--;}
 for(size_t j=0;j<y.size();j++)
   {h[Transf(y[j])]++;
   }time++;
   }
 }
//记录完毕开始找硬币
for(int i=0;i<12;i++)
{if(a[i]>=1){c[i]=true;}
else if(a[i]==0&&l[i]==-time){key=i;flag=" is the counterfeit coin and it is light.";}
else if(a[i]==0&&h[i]==time){key=i;flag=" is the counterfeit coin and it is heavy.";}
else if(a[i]==0&&l[i]<0&&h[i]>0){c[i]=true;}
else {c[i]=true;}
 }
if(key!=0)
{char m;
m='A'+key;
cout<<m<<flag<<endl;}
else
{for(int i=0;i<12;i++)
 {if(c[i]==false)
   {key=i;
   if(l[i]<0){flag=" is the counterfeit coin and it is light.";}
   else{flag=" is the counterfeit coin and it is heavy.";}
   }
 }
char m;
m='A'+key;
 cout<<m<<flag<<endl;
}
	return 0;
}

发表于 2020-02-14 20:45:47 回复(1)
gg 
发表于 2020-02-03 21:56:47 回复(0)
//思想:even的时候表示都是好硬币mark[i]=true
//把重的用z数组存起来,轻的用q数组存起来
//如果有硬币只存在于一组重的一边而不存在于另一组,那么这个硬币一定不是坏硬币,轻的同理
//遍历重的数组,如果存在一个重的组合找不到该硬币,那么该硬币就是好硬币,mark[i]=true
//轻的同理
//最后遍历重的数组轻的数组,如果有一个硬币mark[i]仍然=false,则该硬币就是坏的,在轻的数组中找出来就是轻的,重的数组中找出来就是重的

#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<string.h>
#include<string>
#include<stdio.h>
#include<math.h>
#include<map>
using namespace std;
string z[3],q[3];
bool mark[12];
int main()
{
	string a,b,con;
	while(cin>>a>>b>>con)
	{
		int size=0;
		memset(mark,0,sizeof(mark));
		if(con=="even")
		{
			for(int i=0;i<a.size();i++)
			{
				mark[a[i]-'A']=true;
				mark[b[i]-'A']=true;
			}
		}
		else if(con=="up")
		{
			z[size]+=a;
			q[size]+=b;
			size++;
		}
		else {
			z[size]+=b;
			q[size]+=a;
			size++;
		}
		for(int i=0;i<2;i++)
		{
			cin>>a>>b>>con;
			if(con=="even")
			{
				for(int i=0;i<a.size();i++)
				{
					mark[a[i]-'A']=true;
					mark[b[i]-'A']=true;
				}
			}
			else if(con=="up")
			{
				z[size]+=a;
				q[size]+=b;
				size++;
			}
			else {
				z[size]+=b;
				q[size]+=a;
				size++;
			}
		}
		for(int i=0;i<size-1;i++)
		for(int j=i+1;j<size;j++)
		for(int m=0;m<q[i].size();m++)
		{
			if(q[j].find(q[i][m])==string::npos)
			mark[q[i][m]-'A']=true;
			if(z[j].find(z[i][m])==string::npos)
			mark[z[i][m]-'A']=true;
		}
		bool stop=false;
		for(int i=0;i<size&&!stop;i++)
		for(int j=0;j<q[i].size();j++)
		{
			if(!mark[q[i][j]-'A'])
			{
				stop=true;
				printf("%c is the counterfeit coin and it is light.\n",q[i][j]);
				break;
				
			}
			else if(!mark[z[i][j]-'A'])
			{
				stop=true;
				printf("%c is the counterfeit coin and it is heavy.\n",z[i][j]);
				break;
			}
		}
		
	}
 } 

发表于 2020-02-01 11:49:47 回复(0)
#include <stdio.h>
#include <string.h>

using namespace std;

#define normal   1
#define heavy    2
#define light    5

int confirm[12];

char str0[10], str1[10], str2[10];

void proce() {
	if (strcmp(str2, "even") == 0) {
		for (int i = 0; i < strlen(str0); i++) {
			confirm[str0[i] - 'A'] = normal;
			confirm[str1[i] - 'A'] = normal;
		}
	}
	if (strcmp(str2, "up") == 0) {
		for (int i = 0; i < strlen(str0); i++) {
			if (confirm[str0[i] - 'A'] >= heavy && confirm[str0[i] - 'A'] < light)
				confirm[str0[i] - 'A']++;
			if (confirm[str1[i] - 'A'] >= light)
				confirm[str1[i] - 'A']++;
			if (confirm[str0[i] - 'A'] == 0)
				confirm[str0[i] - 'A'] = heavy;
			if (confirm[str0[i] - 'A'] >= light)
				confirm[str0[i] - 'A'] = normal;
			if (confirm[str1[i] - 'A'] == 0)
				confirm[str1[i] - 'A'] = light;
			if (confirm[str1[i] - 'A'] >= heavy && confirm[str1[i] - 'A'] < light)
				confirm[str1[i] - 'A'] = normal;
		}
	}
	if (strcmp(str2, "down") == 0) {
		for (int i = 0; i < strlen(str0); i++) {
			if (confirm[str0[i] - 'A'] >= light)
				confirm[str0[i] - 'A']++;
			if (confirm[str1[i] - 'A'] >= heavy && confirm[str1[i] - 'A']<light)
				confirm[str1[i] - 'A']++;
			if (confirm[str0[i] - 'A'] == 0)
				confirm[str0[i] - 'A'] = light;
			if (confirm[str0[i] - 'A'] >= heavy && confirm[str0[i] - 'A'] < light)
				confirm[str0[i] - 'A'] = normal;
			if (confirm[str1[i] - 'A']==0)
				confirm[str1[i] - 'A'] = heavy;
			if (confirm[str1[i] - 'A'] >= light)
				confirm[str1[i] - 'A'] = normal;
		}
	}
}

int main() {
	while (scanf("%s%s%s", str0, str1, str2) != EOF) {
		memset(confirm, 0, sizeof(confirm));
		proce();
		for (int i = 0; i < 2; i++) {
			scanf("%s%s%s", str0, str1, str2);
			proce();
		}
		bool fag = true;
		int max1=0, max2=0;
		int c1, c2;
		for (int i = 0; i < 12; i++) {
			if (confirm[i]>2&&confirm[i]<5)
				if (max1 < confirm[i]) {
					max1 = confirm[i];
					c1 = i;
				}
			if (confirm[i] >5)
				if (max2 < confirm[i]) {
					max2 = confirm[i];
					c2 = i;
				}
		}
		if (max1 != 0 || max2 != 0) {
			fag = false;
			if (max1 - 2 > max2 - 5) {
				printf("%c is the counterfeit coin and it is heavy.\n", c1 + 'A');
			}
			else
				printf("%c is the counterfeit coin and it is light.\n", c2 + 'A');
		}
		if(fag)
			for (int i = 0; i < 12; i++) {
				if (confirm[i] == heavy)
					printf("%c is the counterfeit coin and it is heavy.\n", i+'A');
				if (confirm[i] == light)
					printf("%c is the counterfeit coin and it is light.\n", i+'A');
			}
	}
	return 0;
}
有冗余代码
发表于 2019-08-31 21:51:29 回复(0)
/*
对照:False Coin题目
采用weight记录对应物品的总量
首先天平的状态存在3种情况
当状态为"even"时,天平两遍的硬币都是正常的
当状态为"up"时,说明左边比右边中,左边物品的总量+1,右边物品的总量-1
当状态为"down"时,说明右边比左边中,右边物品的总量+1,左边物品的总量-1
同时记录天平不平衡时间发生的次数cnt

最后如果
①若存在w[i]=cnt,则物品i为超重的物品
①若存在w[i]=-cnt,则物品i为较轻的物品
*/
#include <iostream>
#include <map>
#include <string>
using namespace std;

map<char,bool> isGood;//是否正确
map<char,int> Weight;//重量

int main()
{
    string left,right,judge;
    int couter = 0;
    for(int k=0;k<3;k++){
        cin>>left>>right>>judge;
        int len1=left.size();
        int len2=right.size();
        if(judge=="even"){
            for(int i=0;i<len1;i++){
                isGood[left[i]]=true;
            }
            for(int i=0;i<len2;i++){
                isGood[right[i]]=true;
            }
        }
        else if(judge=="up"){//>
            couter++;
            for(int i=0;i<len1;i++){
                Weight[left[i]]++;
            }
            for(int i=0;i<len2;i++){
                Weight[right[i]]--;
            }
        }
        else if(judge=="down"){//<
            couter++;
            for(int i=0;i<len1;i++){
                Weight[left[i]]--;
            }
            for(int i=0;i<len2;i++){
                Weight[right[i]]++;
            }
        }
    }

    for(auto it=Weight.begin();it!=Weight.end();it++){
        if(isGood[it->first])continue;
//        cout<<it->first<<" "<<it->second<<endl;
        if(it->second==couter){
            cout<<it->first<<" is the counterfeit coin and it is heavy."<<endl;
            break;
        }
        else if(it->second==-couter){
            cout<<it->first<<" is the counterfeit coin and it is light."<<endl;
            break;
        }
    }

    return 0;
}
/*
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even
*/

发表于 2019-04-05 20:12:51 回复(0)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>

using namespace std;

map<char,bool> rightCoin;
map<char,int> coin;
void solve(string left, string right ,string ans)
{

    if(ans == "even")
    {
        for(int i = 0 ;i<left.length();i++)
        {
            rightCoin[left[i]] = true;
        }
        for(int i = 0 ;i<right.length();i++)
        {
            rightCoin[right[i]] = true;
        }
    }
    else if(ans == "up")
    {
        for(int i = 0 ;i<left.length();i++)
        {
            if(rightCoin[left[i]] == true)
            continue;
            coin[left[i]]++;
        }
        for(int i = 0 ;i<right.length();i++)
        {
            if(rightCoin[right[i]] == true)
            continue;
            coin[right[i]]--;
        }
    }
    else if(ans == "down")
    {
        for(int i = 0 ;i<left.length();i++)
        {
            if(rightCoin[left[i]] == true)
            continue;
            coin[left[i]]--;
        }
        for(int i = 0 ;i<right.length();i++)
        {
            if(rightCoin[right[i]] == true)
            continue;
            coin[right[i]]++;
        }
    }
}
int main()
{
    string left,right,ans;
    while(cin >> left >> right >> ans)
    {    
        rightCoin.clear();
        coin.clear();

        solve(left,right,ans);
        cin >> left >> right >> ans;
        solve(left,right,ans);
        cin >> left >> right >> ans;
        solve(left,right,ans);
        char ans = ' ';
        int maxx = -1;
        for(int i = 0;i<12;i++)
        {
            if(rightCoin['A' + i] == true)
            continue;

            if(abs(coin['A' + i]) > maxx)
            {
                maxx = abs(coin['A' + i]);
                ans = 'A' + i;
            }
        }
        cout << ans << " is the counterfeit coin and it is ";
        if(coin[ans] > 0)
        {
            cout << "heavy." << endl;
        }
        else
        cout << "light." << endl;
    }
}
发表于 2019-03-04 19:10:19 回复(0)
#include <iostream>
#include <string>
using namespace std;
int main(){
    string s1[3],s2[3],w[3];
    int a[100]={0},n=0;
    for(int i=0;i<3;i++)
        cin>>s1[i]>>s2[i]>>w[i];
    for(int i=0;i<12;i++){
        a['A'+i]=1;
        char c='A'+i;
        int sum1[3]={0},sum2[3]={0};
        for(int j=0;j<s1[n].length();j++)
            sum1[n]+=a[s1[n][j]];
        for(int j=0;j<s2[n].length();j++)
            sum2[n]+=a[s2[n][j]];
        if(sum1[n]==sum2[n]&&w[n]=="even")
            n++;
        else if(sum1[n]>sum2[n]&&w[n]=="down")
            n++;
        else if(sum1[n]<sum2[n]&&w[n]=="up")
            n++;
        else{
            a['A'+i]=0;
            n=0;
            continue;
        }
        for(int j=0;j<s1[n].length();j++)
            sum1[n]+=a[s1[n][j]];
        for(int j=0;j<s2[n].length();j++)
            sum2[n]+=a[s2[n][j]];
        if(sum1[n]==sum2[n]&&w[n]=="even")
            n++;
        else if(sum1[n]>sum2[n]&&w[n]=="down")
            n++;
        else if(sum1[n]<sum2[n]&&w[n]=="up")
            n++;
        else{
            a['A'+i]=0;
            n=0;
            continue;
        }
        for(int j=0;j<s1[n].length();j++)
            sum1[n]+=a[s1[n][j]];
        for(int j=0;j<s2[n].length();j++)
            sum2[n]+=a[s2[n][j]];
        if(sum1[n]==sum2[n]&&w[n]=="even"){
            cout<<c<<" is the counterfeit coin and it is light."<<endl;
            break;
        }
        else if(sum1[n]>sum2[n]&&w[n]=="down"){
            cout<<c<<" is the counterfeit coin and it is light."<<endl;
            break;
        }
        else if(sum1[n]<sum2[n]&&w[n]=="up"){
            cout<<c<<" is the counterfeit coin and it is light."<<endl;
            break;
        }
        else{
            a['A'+i]=0;
            n=0;
            continue;
        }
    }
    for(int i=0;i<12;i++){
        a['A'+i]=-1;
        char c='A'+i;
        int sum1[3]={0},sum2[3]={0};
        for(int j=0;j<s1[n].length();j++)
            sum1[n]+=a[s1[n][j]];
        for(int j=0;j<s2[n].length();j++)
            sum2[n]+=a[s2[n][j]];
        if(sum1[n]==sum2[n]&&w[n]=="even")
            n++;
        else if(sum1[n]>sum2[n]&&w[n]=="down")
            n++;
        else if(sum1[n]<sum2[n]&&w[n]=="up")
            n++;
        else{
            a['A'+i]=0;
            n=0;
            continue;
        }
        for(int j=0;j<s1[n].length();j++)
            sum1[n]+=a[s1[n][j]];
        for(int j=0;j<s2[n].length();j++)
            sum2[n]+=a[s2[n][j]];
        if(sum1[n]==sum2[n]&&w[n]=="even")
            n++;
        else if(sum1[n]>sum2[n]&&w[n]=="down")
            n++;
        else if(sum1[n]<sum2[n]&&w[n]=="up")
            n++;
        else{
            a['A'+i]=0;
            n=0;
            continue;
        }
        for(int j=0;j<s1[n].length();j++)
            sum1[n]+=a[s1[n][j]];
        for(int j=0;j<s2[n].length();j++)
            sum2[n]+=a[s2[n][j]];
        if(sum1[n]==sum2[n]&&w[n]=="even"){
            cout<<c<<" is the counterfeit coin and it is heavy."<<endl;
            break;
        }
        else if(sum1[n]>sum2[n]&&w[n]=="down"){
            cout<<c<<" is the counterfeit coin and it is heavy."<<endl;
            break;
        }
        else if(sum1[n]<sum2[n]&&w[n]=="up"){
            cout<<c<<" is the counterfeit coin and it is heavy."<<endl;
            break;
        }
        else{
            a['A'+i]=0;
            n=0;
            continue;
        }
    }
}
发表于 2018-08-03 10:22:32 回复(0)
#include<iostream>
#include<cstring>
using namespace std;
char Left[3][7];
char Right[3][7];
char result[3][7];
bool IsFake(char c, bool light) {
 for (int i = 0; i < 3; ++i) {
  char *pLeft, *pRight;
  if (light) {
   pLeft = Left[i];
   pRight = Right[i];
  }
  else {
   pLeft = Right[i];
   pRight = Left[i];
  }
  switch (result[i][0])
  {
  case 'u':
   if (strchr(pRight, c) == NULL)
    return false;
   break;
  case 'e':
   if (strchr(pLeft, c) || strchr(pRight, c))
    return false;
   break;
  case 'd':
   if (strchr(pLeft, c) == NULL)
    return false;
   break;
  default:
   break;
  }
 }
 return true;
}
int main() {
 int t;
 cin >> t;
 while (t--) {
  for (int i = 0; i < 3; ++i)
   cin >> Left[i] >> Right[i] >> result[i];
  for (char c = 'A'; c <= 'L'; ++c) {
   if (IsFake(c, true)) {
    cout << c << " is the counterfeit coin and it is light." << endl;
    break;
   }
   else if (IsFake(c, false)) {
    cout << c << " is the counterfeit coin and it is heavy." << endl;
    break;
   }
  }
 }
 return 0;
}

发表于 2017-08-06 17:25:49 回复(1)
以下纯属瞎蒙:
`vec`:可信度;
`wgt`:重量评分;
从可信度最低的硬币组中,选取重量评分的绝对值最高的那个硬币,若其 wgt 估值为负,则为 “heavy”,否则 “light”。
(虽然通过了测试,但不保证理论正确)
bool process()
{
    typedef std::vector<int> vec_t;
    vec_t vec(12U, 0), wgt(12U, 0);

    for (int times = 0; times < 3; ++times) {
        std::string left, right, act;
        std::cin >> left >> right >> act;
        int weight = (act == "even" ? 0 : (act == "up" ? 1 : -1));
        int delta  = (act == "even" ? 1 : -1);
        for (size_t i = 0U, n = left .size(); i < n; ++i) {
            vec[left [i - 0U] - 'A'] += delta;
            wgt[left [i - 0U] - 'A'] -= weight;
        }
        for (size_t i = 0U, n = right.size(); i < n; ++i) {
            vec[right[i - 0U] - 'A'] += delta;
            wgt[right[i - 0U] - 'A'] += weight;
        }
    }

    int val = *std::min_element(vec.begin(), vec.end());
    int idx = -1;
    for (size_t i = 0U; i < 12U; ++i)
        if (vec[i] == val && (idx == -1 || std::abs(wgt[i]) > std::abs(wgt[idx])))
            idx = i;

    std::cout << char('A' + idx)
              << " is the counterfeit coin and it is "
              << (wgt[idx] > 0 ? "light": "heavy")
              << ".\n";
    return true;
}

发表于 2017-03-14 21:01:39 回复(0)

问题信息

难度:
20条回答 4883浏览

热门推荐

通过挑战的用户

查看代码