POJ1013原题:称硬币
提示:C语言版老师讲解视频 该文为java解法
前言
来自编者的话:或许这段日子会很苦,想停下去,但是咬牙坚持下去,一定会有所收获。
一、题目描述
有12枚硬币。其中有11枚真币和1枚假币。假币和真币重量不同, 但不知道假币比真币轻还是重。现在用一架天平称了这些币三次,告诉你称的结果,请你找出假币并且确定假币是轻是重(数据保证一能找出来)。
输入 第一行是测试数据组数。 每组数据有三行,每行表示一次称量的结果。银币标号为A-L。每次称量的结果用三个以空格隔开的字符串表示:天平左边放置的硬币,天平右边放置的硬币平衡状态。其中平衡状态用"up",“down”,或"even"表示, 分别为右端高、右端低和平衡。天平左右的硬币数总是相等的。
输出 输出哪一个标号的银币是假币,并说明它比真币轻还是重。
输入样例 1 ABCD EFGH even ABCI EFJK up ABIJ EFGH even
输出样例 K is the counterfeit coin and it is light.
二、解题思路
1.简化并理解题意
这一点十分重要,要学会简化题意。 十二枚硬币(A-L)中有一枚假币,不知道轻还是重,现在告诉你三次测量的结果,找出假币并确定轻重。题上给了一组测量结果,并且平衡状态都是根据天平右边做出判断,所以要以右边为主对象,并且结果要用字符串表示,最终结果是输入题上案例,并获得正确答案,所有不要忘记写输入这一块的代码。
2.思考方向
借助数组来存输入的字符和显示的结果;使用枚举法,全部12枚硬币都试,对每一枚硬币先假设是假且轻,然后带入三次称量结果中,不符合的话,就假设硬币是假币且重,看看是否符合称量结果。
代码展示:
import java.util.Scanner;
public class class1 {
static String content[][] = new String [3][3];
public static void main(String[]args) {
Scanner s = new Scanner(System.in);
int group = s.nextInt();
while(group-->0) {
for(int i = 0;i<3;i++)
for(int j = 0;j<3;j++)
content[i][j]=s.next();
for(char c ='A';c<='L';c++) {
String a = String.valueOf(c);
if(isfake(content, a, true)) {
System.out.println(a+" is the counterfeit coin and it is light");
break;
}else if(isfake(content, a, false)) {
System.out.println(a+" is the counterfeit coin and it is heavy");
break;
}
}
}
}
static boolean isfake(String[][]content1,String c,boolean light) {
for(int i =0 ;i<3;i++) {
String l = null;
String r = null;
if(light==true) {
l = content1[i][0];
r = content1[i][1];
}else {
l = content1[i][1];
r = content1[i][0];
}
switch (content1[i][2]) {
case "up":
if(r.contains(c)==false)
return false;
break;
case "even":
if(r.contains(c)==true || l.contains(c) == true)
return false;
break;
case "down":
if(l.contains(c)==false)
return false;
break;
}
}
return true;
}
}
帮助理解:就拿当假币为A时举例,首先 进入isfake方法中,默认为true,将l=ABCD r=EFGH,结果为even,进入switch循环中,判断存在,return false终止函数,重新返回到主函数中,由于light没有返回值,矛盾,所以默认进行下一个字符。
当轮到假币K时,进入isfake中返回值为true,所以最终确定假币,假设成功,为轻。
目的
学会从题意着手,熟练使用枚举。
参考文章:C语言版解法
|