假币问题
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
- 赛利有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.
来源
-
East Central North America 1998
计算概论05 - 解题思路:我用了三个数组name,state,count分别保存12枚硬币的标号,真假状态,假的状态统计次数。用string的二维数组记录三次称量数据,每次数据判断,如果为“even”则该次称量的所有硬币对应的state从初始态0赋值为真10;如果是“up”则左边的硬币如果是初始态0赋值为重1,如果是真10跳过,如果是轻-1说明这个硬币为真赋值为10,右边的硬币如果是初始态0赋值为轻-1, 如果是真10跳过,如果是重1说明这个硬币为真赋值为10;如果是“down”则和“up”的左右相反即可。
- 踩中的坑:如果数据为**AB **** up (*为真币)
-
**** AB** down
-
**** ***B down 这样的数据如果不加上count假的次数就无法排除A的干扰。
-
import java.util.Scanner; public class Main { public static void main(String[] args) { char[] name = new char[12];//用来记录十二枚硬币的 int[] state = new int[12];//用来统计十二枚硬币状态的 int[] count = new int[12];//用来统计计算了几次不平衡状态 int i,j; int n; Scanner s = new Scanner(System.in); n = s.nextInt();s.nextLine(); while(n-- != 0) { //为每次name数组和state赋初值 for(i=0;i<12;i++) { name[i] = (char)(65+i); state[i] = 0; count[i] = 0; } String[][] data = new String[3][];//用二维string数组记录三次比较结果的 for(i=0;i<3;i++) { String line = s.nextLine();//读入一行数据 data[i] = line.split(" ");//以空格为间隔划分为数组 } for(i=0;i<3;i++) { if(data[i][2].equals("even")) {//如果结果为平衡,为此次比较的所有硬币赋一个真状态10 for(j=0;j<12;j++) { if(data[i][0].contains(String.valueOf(name[j]))) { state[j] = 10; } if(data[i][1].contains(String.valueOf(name[j]))) { state[j] = 10; } } }else if(data[i][2].equals("up")) {//如果结果是右边高,则为左边的不是已经确定为真赋一个重状态1 for(j=0;j<12;j++) { //如果该硬币在此前被赋予了一个轻状态-1,则该硬币赋为真。 if(data[i][0].contains(String.valueOf(name[j])) && state[j] != 10) {//将名字char型转化为string型进行查询该string中是否具有此硬币 if(state[j] == -1) { state[j] = 10;continue; }else { state[j] = 1; count[j]++; } } if(data[i][1].contains(String.valueOf(name[j])) && state[j] != 10) { if(state[j] == 1) {//与上一条相反 state[j] = 10;continue; }else { state[j] =-1; count[j]++; } } } }else if(data[i][2].equals("down")) { for(j=0;j<12;j++) { if(data[i][0].contains(String.valueOf(name[j])) && state[j] != 10) { if(state[j] == 1) { state[j] = 10;continue; }else { state[j] = -1; count[j]++; } } if(data[i][1].contains(String.valueOf(name[j])) && state[j] != 10) { if(state[j] == -1) { state[j] = 10;continue; }else { state[j] =1; count[j]++; } } } } } int max = -1; int maxAddress = -1; for(i=0;i<12;i++) { if(state[i] != 10 && state[i] != 0) { if(max < count[i]) { max = count[i]; maxAddress = i; } } } if(state[maxAddress] == -1) { System.out.printf(name[maxAddress] + " is the counterfeit coin and it is light.\n"); }else{ System.out.printf(name[maxAddress] + " is the counterfeit coin and it is heavy.\n"); } } s.close(); } }