Java语言实现ALGO-194 审美课 (算法训练)



参考代码:如果觉得我的代码写的还可以的话可以点个赞,支持我,谢谢。

如果java快速输入的方法不懂的可以参考我的另一篇博客:https://blog.csdn.net/zxt1484675627/article/details/88595542

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		Reader.init(System.in);
		int n=Reader.nextInt();
		int m=Reader.nextInt();
		int x;
		int num;//存某一个学生的二进制所有答案
		Map<Integer,Integer> map=new HashMap<Integer,Integer>();
		for(int i=0;i<n;i++) {
			num=0;
			for(int j=0;j<m;j++) {//每个学生的答案都转换为一个二进制数(m个01串),只是实际用十进制表示
				x=Reader.nextInt();
				num=(num<<1)+x;//num左移1位,注意移位运算优先级比加减低必须打括号
			}
			map.put(num, map.containsKey(num) ? map.get(num)+1 : 1);//记录一样的答案
		}

		int sum=0;
		int max=(1<<m)-1;//1左移m位,即2^m-1(表示为二进制即为m个1,只是实际用十进制表示)
		for(Map.Entry<Integer, Integer> entry:map.entrySet()) {//遍历不同的二进制集合选择其相反数
			x=entry.getKey()^max;//a[i]与2^m-1作异或运算,求相反的那个数的十进制(过程用的二进制)
			if(map.containsKey(x))
				sum+=map.get(x)*entry.getValue();//答案数加上相反的那个答案集的个数乘以自己本身的个数
		}
		System.out.println(sum/2);//因为相反数互相都加了,所有sum/2
	}

}

class Reader{
	static BufferedReader reader;
	static StringTokenizer tokenizer;
	
	public static void init(InputStream in) {
		reader=new BufferedReader(new InputStreamReader(in));
		tokenizer=new StringTokenizer("");
	}

	public static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	public static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	
	private static String next() throws IOException {
		while(!tokenizer.hasMoreTokens()) {
			tokenizer=new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
	
}


一开始暴力破解的代码(超时):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		Reader.init(System.in);
		int n=Reader.nextInt();
		int m=Reader.nextInt();
		int a[][]=new int[n][m];
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				a[i][j]=Reader.nextInt();
			}
		}
		
		int count=0;
		boolean flag;
		for(int i=0;i<n-1;i++) {
			for(int j=i+1;j<n;j++) {
				flag=true;
				for(int k=0;k<m;k++) {
					if(a[i][k]==a[j][k]) {
						flag=false;
						break;
					}
				}
				if(flag) {
					count++;
				}
			}
		}
		System.out.println(count);
	}

}

class Reader{
	static BufferedReader reader;
	static StringTokenizer tokenizer;
	
	public static void init(InputStream in) {
		reader=new BufferedReader(new InputStreamReader(in));
		tokenizer=new StringTokenizer("");
	}

	public static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	public static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	
	private static String next() throws IOException {
		while(!tokenizer.hasMoreTokens()) {
			tokenizer=new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
	
}

参考别人C++代码写的代码: 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		Reader.init(System.in);
		int n=Reader.nextInt();
		int m=Reader.nextInt();
		int x;
		int[] a=new int[n];//存所有学生的二进制答案
		Map<Integer,Integer> map=new HashMap<Integer,Integer>();
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {//每个学生的答案都转换为一个二进制数(m个01串),只是实际用十进制表示
				x=Reader.nextInt();
				a[i]=(a[i]<<1)+x;//a[i]左移1位,注意移位运算优先级比加减低必须打括号
			}
			map.put(a[i], map.containsKey(a[i]) ? map.get(a[i])+1 : 1);//记录一样的答案
		}

		int sum=0;
		int max=(1<<m)-1;//1左移m位,即2^m-1(表示为二进制即为m个1,只是实际用十进制表示)
		for(int i=0;i<n;i++) {//按行选择相反数
			x=a[i]^max;//a[i]与2^m-1作异或运算,求相反的那个数的十进制(过程用的二进制)
			if(map.containsKey(a[i])&&map.containsKey(x)) {
				sum+=map.get(a[i])*map.get(x);//答案数加上相反的那个答案集的个数乘以自己本身的个数
				map.remove(a[i]);//去掉重复的
			}		
		}
		System.out.println(sum);
	}

}

class Reader{
	static BufferedReader reader;
	static StringTokenizer tokenizer;
	
	public static void init(InputStream in) {
		reader=new BufferedReader(new InputStreamReader(in));
		tokenizer=new StringTokenizer("");
	}

	public static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	public static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
	
	private static String next() throws IOException {
		while(!tokenizer.hasMoreTokens()) {
			tokenizer=new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
	
}

参考链接:c++:https://blog.csdn.net/DanBo_C/article/details/88184414

java:https://blog.csdn.net/qq_42835910/article/details/87448444

有时间的也可以参考一下这位大佬的博客,不同的解题思路,输入方式代码比较少,代码也是对的:

https://blog.csdn.net/qq_40674583/article/details/87909178

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值