假币问题

假币问题

总时间限制: 
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();
	}
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值