题目描述:
你就是一个画家!你现在想绘制一幅画,但是你现在没有足够颜色的颜料。为了让问题简单,我们用正整数表示不同颜色的颜料。你知道这幅画需要的n种颜色的颜料,你现在可以去商店购买一些颜料,但是商店不能保证能供应所有颜色的颜料,所以你需要自己混合一些颜料。混合两种不一样的颜色A和颜色B颜料可以产生(A XOR B)这种颜色的颜料(新产生的颜料也可以用作继续混合产生新的颜色,XOR表示异或操作)。本着勤俭节约的精神,你想购买更少的颜料就满足要求,所以兼职程序员的你需要编程来计算出最少需要购买几种颜色的颜料?
输入描述:
第一行为绘制这幅画需要的颜色种数n (1 ≤ n ≤ 50)
第二行为n个数xi(1 ≤ xi ≤ 1,000,000,000),表示需要的各种颜料.
输出描述:
输出最少需要在商店购买的颜料颜色种数,注意可能购买的颜色不一定会使用在画中,只是为了产生新的颜色。
解题思路:
将每一个数些为二进制,得到一个n*30的矩阵,此时最少的颜料数即为矩阵的秩。
代码:
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] s = br.readLine().split(" ");
br.close();
int[] arr = new int[s.length];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(s[i]);
}
//从矩阵最后一行向前比较
Arrays.sort(arr);
int last = arr.length - 1;
int cnt = 1;
//将矩阵转换为下三角矩阵,矩阵的秩等于cnt的值
//原理:数组是由小到大排序的,当high(num1) != high(num2)时,num1的
//最高位为1,且无法被消去,故矩阵的秩+1.
while(last > 0 && arr[last-1] != 0) {
int num1 = arr[last];
int num2 = arr[last-1];
if (high(num1) == high(num2)) {
arr[last-1] = num1 ^ num2;
Arrays.sort(arr);
}else {
last--;
cnt++;
}
}
System.out.println(cnt);
}
// 求出当前数字的最高位
private static int high(int n) {
int cnt = 0;
while (n > 0) {
cnt++;
n /= 2;
}
return cnt;
}
}