混合颜料(类似矩阵求秩)

题目描述

你就是一个画家!你现在想绘制一幅画,但是你现在没有足够颜色的颜料。为了让问题简单,我们用正整数表示不同颜色的颜料。你知道这幅画需要的n种颜色的颜料,你现在可以去商店购买一些颜料,但是商店不能保证能供应所有颜色的颜料,所以你需要自己混合一些颜料。混合两种不一样的颜色A和颜色B颜料可以产生(A XOR B)这种颜色的颜料(新产生的颜料也可以用作继续混合产生新的颜色,XOR表示异或操作)。本着勤俭节约的精神,你想购买更少的颜料就满足要求,所以兼职程序员的你需要编程来计算出最少需要购买几种颜色的颜料?

输入描述:

第一行为绘制这幅画需要的颜色种数n (1 ≤ n ≤ 50)
第二行为n个数x
i
(1 ≤ x
i
 ≤ 1,000,000,000),表示需要的各种颜料.

输出描述:

输出最少需要在商店购买的颜料颜色种数,注意可能购买的颜色不一定会使用在画中,只是为了产生新的颜色。
示例1

输入

3
1 7 3

输出

3

 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 /**
 5  * 
 6  * 混合颜料
 7  * @author Dell
 8  *
 9  *
10  *将所需的颜料数字转换成二进制自上向下排列
11  *如:  1 7 3
12  *    0001
13  *    0111
14  *    0011
15  *    进行亦或运算就是 取上下不同的
16  *    a⊕b = (¬a ∧ b) ∨ (a ∧¬b)
17  *如:0001 XOR 0111 = 0110 = 6
18  *
19  * 当一种颜料不能被其他颜料配出来时,我们就必须购买他
20  * 通过观察可以发现 这与 矩阵的变换 求秩类似
21  * 
22  * 我们现在也需要  从小到大排列 颜色数字
23  * 依次消去前边的 1
24  *  消1时如果下边的树肯定大,如果异或得到的数比 上边的数小 ,说明消掉了 1可以保存,
25  *  如果异或 结果大 说明此过程 时 1^0 = 1不是消1 不保存
26  * 
27  */
28 public class Main {
29 public static void main(String[] args) {
30     Scanner sc = new Scanner(System.in);
31     int n = sc.nextInt();
32     int [] sx = new int[n];
33     for (int i = 0; i < sx.length; i++) {
34         sx[i] = sc.nextInt();
35     }
36     Arrays.sort(sx);
37     for (int i = sx.length-1; i>0 ; i--) {
38         for (int j = i-1; j >=0; j--) {
39             if ((sx[j]^sx[i])<sx[j]) {
40                 sx[j] = sx[j]^sx[i];
41             }    
42         }
43     }
44     int count = 0;
45     for (int i = 0; i < sx.length; i++) {
46         if (sx[i]!=0) {
47             count++;
48         }
49     }
50     System.out.println(count);
51 }
52 }
原文地址:https://www.cnblogs.com/the-wang/p/8979302.html