混合颜料(求矩阵的秩问题)

感觉这是一个思路还挺奇特的题目,算是一种新思路积累吧。反正是第一次用code求一个矩阵的秩,我还是太差啦...努力空间太大


1、题目:

题目描述

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

输入描述:

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

输出描述:

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

输入

3
1 7 3

输出

3



2、思想:参考牛油的

链接:https://www.nowcoder.com/questionTerminal/5b1116081ee549f882970eca84b4785a
来源:牛客网

和线性代数里求线性方程组差不多,通过线性变换求极大线性无关组。而题目把“线性变换”改成了“异或变换”,原理是一样的,就是求一组能表示所有颜色的“基”,最后保留一个上三角矩阵。一个数是由32位表示的,那么我们可以把一个数看成是32维空间的一个向量。最后形成了一个n*32的矩阵,然后就可以按照我们线性代数的方法进行变换啦,变成上三角矩阵,最后剩几行就是需要几种颜色。



3、code:已a

package schooloffer17;

import java.util.Arrays;
import java.util.Scanner;

/**
 * Created by caoxiaohong on 17/11/11 10:43.
 * <混合颜料></>
 * 本题实质:求矩阵的秩
 * 虽然最后求出来的不一定是类似线性代数的最简表达式,但是只要矩阵中的行表达式的真值!=0,则,这就是当前行没办法被其它行表示,那么就必须作为1阶存在.
 * 所以最后求完之后,只要查找矩阵中有多少个非零的行,就是矩阵的秩.也就是所求.
 */
public class MergeColors {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int n;//n种颜色,1 ≤ n ≤ 50
        while (scanner.hasNextInt()){
            n=scanner.nextInt();
            //输入n个数xi(1 ≤ xi ≤ 1,000,000,000)
            int[] xi=new int[n];
            for(int i=0;i<n;i++)
                xi[i]=scanner.nextInt();

            Arrays.sort(xi);//升序,目的是:为求xi[i]的最高位1做准备.

            for(int i=n-1;i>0;i--){//每循环一次:则行号为[i,n-1]已经不再改变
                for(int j=i-1;j>=0;j--){
                    if(getHighestBit(xi[i])==getHighestBit(xi[j])){
                        xi[j]^=xi[i];
                    }
                }
                Arrays.sort(xi);
            }

            //查找非零行
            int count=0;
            for(int i=0;i<n;i++){
                if(xi[i]!=0)
                    count++;
            }
            System.out.println(count);
        }
    }

    /**
     * 求数字number的二进制表达式中,最高位的1是第多少位
     * @param nunmber
     * @return
     */
    private static int getHighestBit(int nunmber){
        int tmp;
        for(int i=31;i>=0;i--){
            tmp=nunmber>>i;
            tmp&=1;
            if(tmp!=0)
                return i+1;
        }
        return 0;
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值