(ALGO-194)审美学

题目链接
问题描述
  《审美的历程》课上有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。
  
方法一:
  思路:从题目中看出,输入的数据答案部分只有0、1,如果单纯的把其中的每一个0和1都拿和其他几排的0 1比就很麻烦,于是这里我们想到了二进制,由2进制我们就能想到进制转换,进制转换了就好弄啦,我想到的是直接把原来的每行的0和1组合换成一个十进制数字,但是大佬不是这样想的,大佬的做法是把转成的10进制数当做索引,然后每遇到相同的数字就把与该索引对应的数+1。最后算相反数的时候就是对索引和全1进行异或,得到相反的索引,然后两个索引数值进行相乘得出结果(因为数值存的是相同数字出现的次数,相乘就相当于组合)
 
下面这是按平常思路写的,超时了只有90分:

public static void main(String[] args) throws IOException {
		
		
		shenMeiWay1();
	}
	/**
	 * ALGO-194	审美课
	 * 
	 * 法1、以10进制存储(只有90分 超时了)
	 * @param kid
	 * @param pic
	 * @param ss
	 */
	public static void shenMeiWay1() throws IOException {
		BufferedReader input=new BufferedReader(new InputStreamReader(System.in));
		String[] s=input.readLine().split(" ");
		int kid=Integer.parseInt(s[0]);
		int picture=Integer.parseInt(s[1]);
		int[][] array=new int[kid][picture];
		for(int i=0;i<kid;i++) {
			String[] ss=input.readLine().split(" ");
			for(int j=0;j<picture;j++) {
				array[i][j]=Integer.parseInt(ss[j]);
			}
		}
		taste(array,kid,picture);
	}
public static void taste(int[][] array,int kid,int picture) {
			int count=0;
			int[] ten=new int[kid];
			for(int i=0;i<kid;i++) {
				int sum=0;
				for(int j=0;j<picture;j++) {
					sum=(sum<<1)+array[i][j];//转10进制
				}
				ten[i]=sum;
			}
			
			int sum=(1<<picture)-1;    //算出全为1的对应的十进制数
			
			for(int x=0;x<kid;x++) {
				int temp=1;
				while(temp+x<kid) {//注意条件使用
					if(ten[x]+ten[x+temp]==sum) {//相反的内容加起来肯定等于全是1的情况
						count++;
					}
					temp++;
				}
			}
			System.out.println(count);
			
		}

下面是按大佬的思路写的:得了满分

public class Main {	
	public static void main(String[] args) {
		shenMeiWay2();
	}
}
/**
 * ALGO-194	审美课
 * 
 * 法一、以10进制做数组索引
 * @param kid
 * @param pic
 * @param ss
 */
public void shenMeiWay2() throws IOException{
//这道题因为数据量大 用Scanner可能超时 所以用缓冲流超时可能性小些
	BufferedReader input=new BufferedReader(new InputStreamReader(System.in));
	String[] s1={};
	s1 = input.readLine().split(" ");
	int kid=Integer.parseInt(s1[0]);//孩子数量
	int pic=Integer.parseInt(s1[1]);//图片数量
	//int[][] arr=new int[kid][pic];//存所有答案
	String[] ss=new String[kid];//存每个孩子的答案
	for(int i=0;i<kid;i++){
		ss[i]=input.readLine().replace(" ", "");//存成2进制形式
	}
	toTen(kid, pic, ss);
}
public static void toTen(int kid,int pic,String[] ss) {
	int ans=0;//重复次数
	int INF=(1<<pic)-1;//数组tens[]的最大值(就是2进制全为1的那一排转为10进制时)可用来做初始容量
	int[] tens=new int[INF +1];//10进制结果做索引的数组
	for(int i=0;i<kid;i++){
		int ten=0;
		String s=ss[i];
		//以下两步为调用API把2进制转为10进制
		BigInteger bi=new BigInteger(s,2);//java.math.BigInteger的最后一个构造方法,将2进制的数转为BIgInteger
		ten=Integer.parseInt(bi.toString());
		
		tens[ten]++;//每得到相同的10进制数就对此数的索引的值加一
	}
	for (int x = 0; x < tens.length; x++) {
		if (tens[x] != 0) {
			int y=x^INF;//y为x索引的值的完全相反数
			ans=ans+tens[y]*tens[x];//相反的数组值进行组合,所以相乘,但肯定会重复一半
		}
	}
	System.out.print(ans/2);
}

这里我想总结一下二进制转十进制的方法:
方法一:使用api (适用于String类型存储的二进制)

/**
* @Description:	二进制转换成十进制 
* @param binarySource
* @return int
 */
public static int binaryToDecimal(String binarySource) {
	BigInteger bi = new BigInteger(binarySource,2);	//使用第java.math.BigInteger最后一个构造方法,把二进制转换为BigInteger类型
	return Integer.parseInt(bi.toString());		//转换成十进制
}
顺便了解一下他的逆过程。
/**
* @Description: 十进制转换成二进制 ()
* @param decimalSource
* @return String
*/
public static String decimalToBinary(int decimalSource) {
BigInteger bi = new BigInteger(String.valueOf(decimalSource)); //转换成BigInteger类型
return bi.toString(2); //参数2指定的是转化成X进制,默认10进制
}


方法2:使用算法
A:适用于int数组保存的二进制

int[] arr=new int[9];
int ten=0;
for(int i=0;i<arr.length;i++){
	ten=(ten<<1)+arr[i];//每循环一次加上一位数
	}

B、适用于String类型的二进制

String str=1010;
int ten=0;
for(int i=0;i<str.length();i++){
	ten=str.charAt(i)-48;
	}

发布了44 篇原创文章 · 获赞 3 · 访问量 1361

猜你喜欢

转载自blog.csdn.net/weixin_43329639/article/details/104285888
今日推荐