#百练2692 假币问题 #枚举

百练 2692 假币问题

赛利有12枚银币。其中有11枚真币和1枚假币。假币看起来和真币没有区别,但是重量不同。但赛利不知道假币比真币轻还是重。于是他向朋友借了一架天平。朋友希望赛利称三次就能找出假币并且确定假币是轻是重。例如:如果赛利用天平称两枚硬币,发现天平平衡,说明两枚都是真的。如果赛利用一枚真币与另一枚银币比较,发现它比真币轻或重,说明它是假币。经过精心安排每次的称量,赛利保证在称三次后确定假币。

输入格式:

第一行有一个数字n,表示有n组测试用例。
对于每组测试用例:
输入有三行,每行表示一次称量的结果。赛利事先将银币标号为A-L。每次称量的结果用三个以空格隔开的字符串表示:天平左边放置的硬币 天平右边放置的硬币 平衡状态。其中平衡状态用``up'', ``down'', 或 ``even''表示, 分别为右端高、右端低和平衡。天平左右的硬币数总是相等的。

输出格式:

输出哪一个标号的银币是假币,并说明它比真币轻还是重(heavy or light)。

输入样例:

在这里给出一组输入。例如:

1
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even

输出样例:

在这里给出相应的输出。例如:

K is the counterfeit coin and it is light.

代码:

import java.util.*;
class Main {

//0表示真币,-1表示假币比真币轻,1表示假币比真币重
public static int status[]=new int[12];

//比较3次,所以开3个空间
public static String left[]=new String[3];
public static String right[]=new String[3];
public static String result[]=new String[3];

//创建一个判断银币真假的私有方法
private static boolean check(){
int i,k,left_w,right_w;
for(i=0;i<3;i++){
left_w=right_w=0;//定义左右边的重量初始值为0
int len=left[i].length();
for(k=0;k<len;k++){

//计算左边的重量,可能为0,1,-1
left_w+=status[left[i].charAt(k)-'A'];
//计算右边的重量,可能为0,1,-1
right_w+=status[right[i].charAt(k)-'A'];
}
if(left_w>right_w&&!result[i].equals("up")){
return false;
}
if(left_w==right_w&&!result[i].equals("even")){
return false;
}
if(left_w<right_w&&!result[i].equals("down")){
return false;
}
}
return true;
}
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int n=Integer.parseInt(sc.nextLine());
for(int i=0;i<n;i++) {
for(int j=0;j<3;j++) {
String str[] = sc.nextLine().split(" ");
left[j] = str[0];
right[j] = str[1];
result[j] = str[2];
}

//初始化存放银币真假的数组都为真币
for(int j=0;j<12;j++){
status[j]=0;
}

//开始枚举
int j;
for(j=0;j<12;j++){
//假设第j枚银币为-1
status[j]=-1;
if(check()){
break;

//break后找到对应此时的j的值,即第几个银币为假币
}
//假设第j枚银币为1
status[j]=1;
if(check()){
break;
}
status[j]=0;
}
String ans=status[j]>0 ? "heavy.":"light.";
System.out.print((char)('A'+j)+" is the counterfeit coin and it is "+ans+"\n");
}
}
}

详解:

变量定义

  1. status[]: 一个整型数组,用于存储12枚银币的真假状态。其中,0表示真币,-1表示假币比真币轻,1表示假币比真币重。
  2. left[] 和 right[]: 两个字符串数组,用于存储每次比较时左右两边的银币序列。
  3. result[]: 一个字符串数组,用于存储每次比较的结果,可能是"up"(左边重)、"even"(一样重)或"down"(右边重)。

方法定义

  1. check(): 这是一个私有方法,用于检查当前假设的银币真假状态是否满足所有的比较结果。方法内部遍历了所有的比较,并根据银币的状态和比较结果来判断当前假设是否成立。如果所有比较都满足,则返回true,否则返回false

主函数 main(String[] args)

  1. 首先,通过Scanner类从标准输入读取一个整数n,表示有n组银币比较数据。
  2. 然后,对于每组数据,读取一行包含三个字符串的输入,分别表示左右两边的银币序列和比较结果,并将它们存储到left[]right[]result[]数组中。
  3. 接下来,初始化status[]数组,将所有银币的状态都设为真币(即0)。
  4. 然后开始枚举,假设每一枚银币为假币(无论是轻还是重),然后调用check()方法检查当前假设是否成立。如果成立,就找到了假币的位置和真假状态,然后跳出循环。
  5. 最后,根据找到的假币的位置和真假状态,输出假币的字母编号(从A到L)和它是轻的还是重的。

示例

假设输入为:

 
2
ABC DEF up
GHI JKL down

这表示有两组银币比较数据。第一组数据中,左边的银币序列是ABC,右边的银币序列是DEF,比较结果是左边重(即ABC中有一枚假币且比真币重)。第二组数据中,左边的银币序列是GHI,右边的银币序列是JKL,比较结果是右边重(即GHI中有一枚假币且比真币轻)。

根据这些信息,程序会输出:

 
makefileC is the counterfeit coin and it is heavy.
I is the counterfeit coin and it is light.

这表示在第一组数据中,假币是C,且比真币重;在第二组数据中,假币是I,且比真币轻。

  • 48
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值