蓝桥杯 审美课java 代码讲解

问题描述
  《审美的历程》课上有n位学生,帅老师展示了m幅画,其中有些是梵高的作品,另外的都出自五岁小朋友之手。老师请同学们分辨哪些画的作者是梵高,但是老师自己并没有答案,因为这些画看上去都像是小朋友画的……老师只想知道,有多少对同学给出的答案完全相反,这样他就可以用这个数据去揭穿披着皇帝新衣的抽象艺术了(支持帅老师^_^)。
  答案完全相反是指对每一幅画的判断都相反。
输入格式
  第一行两个数n和m,表示学生数和图画数;
  接下来是一个n*m的01矩阵A:
  如果aij=0,表示学生i觉得第j幅画是小朋友画的;
  如果aij=1,表示学生i觉得第j幅画是梵高画的。
输出格式
  输出一个数ans:表示有多少对同学的答案完全相反。
样例输入
3 2
1 0
0 1
1 0
样例输出
2
样例说明
  同学1和同学2的答案完全相反;
  同学2和同学3的答案完全相反;
  所以答案是2。
数据规模和约定
  对于50%的数据:n<=1000;
  对于80%的数据:n<=10000;
  对于100%的数据:n<=50000,m<=20。

本来看着这个提很简单用了三重循环判断就ok了,但是提交上去之后发现只是通过了一半,其余都是时间超时,看来测试数据是非常大的…又去网上找别人的代码。。。。这位大佬的博客~戳戳戳进去----

当然是讲解它的代码。。。

大体的思路是 :
如果两个同学的判断完全相反,那么他们异或之后为全1
例如 011 ^ 100 = 111
我们利用全1 ^ 011 = 100,只要在列表里面查找是否存在100就可以判断有没有完全相反。
所以


**import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map.Entry;**

 

public class Main {

	**private static Reader reader;
	public static void main(String[] args) {
		reader = new InputStreamReader(System.in);
		int n, m;
		n = getInt();
		m = getInt();
		HashMap<Integer, Integer> hm = new HashMap<>(n);**

		

**111、for (int i = 0; i < n; ++i) {
   
   			int num = 0, x = 0;
   
   			for (int j = 0; j < m; j++) {
   
   				x = getInt();
   
   				num = (num << 1) + x;//对于读取进来的二进制转换为十进制的数字
   				//num<<1  表示将二进制的数字向左移动一位
   				例如:
   				3 = 011
   				第一次读取 0  (num<<1)->00  + 0  =>00   num = 0
   				第二次读取 0  (num<<1)->00  + 1  =>01   num = 1
   				第三次读取 1  (num<<1)->10  + 1  =>11   num = 3

   
   			}
   
   			hm.put(num, hm.containsKey(num) ? hm.get(num) + 1 : 1);
   			
   			这个地方是判断是否已经这个答案,如果没有,就将人数变成1;
   			如果说已经有同学是这个答案,那么将人数继续加一。
   
   		}**

222、		**int sum = 0, maxn = (1 << m) - 1;
		for (Entry<Integer, Integer> entry : hm.entrySet()) {
			if (maxn / 2 < entry.getKey())
				continue;
			int key = entry.getKey() ^ maxn;  
			if (hm.containsKey(key))
				sum += hm.get(key) * entry.getValue();
		}
		System.out.println(sum);
		# //拿到一个同学的答案key,取异或之后查找列表里是否有这个答案
		# //hm.get(key) * entry.getValue();  举个栗子:如果有2个人是011 三个人 是 100,那么完全相反的组合共有2*3 = 6对。
		
	}**

 

333、	**public static int getInt() {
		int res = 0, read;
		try {
			while ((read = reader.read()) != -1) {
				if (Character.isDigit(read)) {// 因为全是非负数,不需要判断负号‘-’,只要是数字就行
					res = read - '0';
					while ((read = reader.read()) != -1) {// 继续得到能得到的数字
						if (Character.isDigit(read)) {
							res = res * 10 + (read - '0');
						} else {
							break;
						}
					}
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return res;
	}**

## getInt方法是在提取的字符流reader中逐个判断其中的字符是否是数字字符并提取int,
第一个while保证提取到的res是数字;第二个while保证提取到的数字res的
全部(防止123的的情况只取走了1).

}

大佬就是大佬啊~膜拜!!!
啊继续加油啊!还有九天!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值