第一行为绘制这幅画需要的颜色种数n (1 ≤ n ≤ 50) 第二行为n个数xi(1 ≤ xi ≤ 1,000,000,000),表示需要的各种颜料.
输出最少需要在商店购买的颜料颜色种数,注意可能购买的颜色不一定会使用在画中,只是为了产生新的颜色。
3 1 7 3
3
import java.util.*;
import java.io.*;
public class Main {
/**
*矩阵论中的知识表明,最大线性无关组是解的最基本的形式。
*这个题目类似于求矩阵的最大线性无关组,用高斯消元法就可以了,正向算一遍即可,反向不用计算(我们只关心无关组的向量个数,不关心具体解的形式)。
*多元方程,我们从左到右不为零开始消元,对于二进制数,那就是从大的数开始就可以了。
*用一个函数判断每一位是否为零,为零才消元。遍历的时候注意方程有几个,我们每次遍历的目标是消灭一列的1,使每一列最多1个一,
*但是方程不够的时候,就不必向下消了,已经可以结束了。
*/
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine().trim());
int[] arrColor = new int[n];
String[] arrInput = br.readLine().trim().split(" ");
for (int i=0; i<n; i++) {
arrColor[i] = Integer.parseInt(arrInput[i]);
}
Arrays.sort(arrColor);//排序
int computLoopCnt = 0;//记录循环的个数
for (int i=31; i>=0; i--) {//遍历每一位,最大的数的该位为零就跳过
int row = (n - 1) - computLoopCnt;
if (row <= 0) {//如果行数不够了,直接停止
break;
}
if (isNbitIsOne(arrColor[row],i)) {//判断该为是否为零
computLoopCnt++;
for (int j=row-1; j>=0; j--) {
if (isNbitIsOne(arrColor[j],i)) {
arrColor[j] = arrColor[row] ^ arrColor[j];
}
}
Arrays.sort(arrColor, 0, row );//每次计算后排序,因为异或后可能变大,要正确找到最大的
}
}
int baseNum = 0;
for (int i=0; i<n; i++) {
if (arrColor[i] != 0) {
baseNum++;
}
}
System.out.println(baseNum);
}
public static boolean isNbitIsOne(int a, int n) {//判断第n位(顺寻方向:自右向左)是否为零
if (n > 32) {
throw new IllegalArgumentException();
}
int test = 1 << n;
boolean isOne = false;
if (test == (a & test)) {
isOne = true;
}
return isOne;
}
}
/**
* 思路:前面高票答案都说了,其实题目的本质是求矩阵的秩,矩阵中的每个
* 向量即为每个数的二进制形式。但是矩阵秩的求法是加减运算(高斯消元法),
* 而此题不同之处在于:以异或运算来代替加减运算。
*/
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int count = in.nextInt();
int[] array = new int[count];
for (int i = 0; i < count; i++)
array[i] = in.nextInt();
Arrays.sort(array);
for (int i = count - 1; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--)
if ((array[i] ^ array[j]) < array[j])
array[j] ^= array[i];
}
int res = 0;
for (int i = 0; i < count; i++) {
if (array[i] != 0) res++;
}
System.out.println(res);
}
}
}
//化上三角,求01矩阵的秩,只是操作是异或
//O(n^2) 每次取最大的数换到上面,然后下面的数去清除当前的最高位,再取清除后数中的最大,置换循环
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(input.hasNext()){
int n = input.nextInt();
int[] a = new int[n];
int maxi = 0;
for(int i=0;i<n;i++){
a[i] = input.nextInt();
if(a[maxi]<a[i]) maxi = i;
}
swap(0,maxi,a);
for(int b=0;b<n-1;b++){
maxi = -1;
for(int i=b+1;i<n;i++){
if((a[i]^a[b])<a[i]){
a[i] = a[i]^a[b];
}
if(maxi==-1||a[maxi]<a[i]) maxi = i;
}
swap(b+1,maxi,a);
}
int ans = 0;
for(int i=0;i<n;i++){
//System.out.println(Integer.toBinaryString(a[i]));
if(a[i]>0) ans++;
}
System.out.println(ans);
}
}
public static void swap(int i,int j,int[] a){
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
/**
* 综合了以上很多的见解
* 数组从小到大排列,从最下面一行开始,每次消去最高位的1,比如A行的系数减去B行,直接A = A^B就行
*/
import java.util.*;
public class Main1 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
int n = scan.nextInt();
int[] col = new int[n];
for(int i=0; i<n; i++){
col[i] = scan.nextInt();
}
Arrays.sort(col);
int count = 0;
for(int i=n-1; i>=0; i--){
for(int j=i-1; j>=0; j--){
/**
* 如果两者的最高位相同,说明最高位可以消掉,
* 将两者 xor ,或者说将矩阵两行相减消掉最高位
*/
if(highbit(col[i]) == highbit(col[j])){
/** 如果两个最大数的最高位可以消掉,那么消除之后,最大数已被消掉,没有用了
如果两个最大数的最高位不可以消掉,那么结果+ 1 ,最大数也没有用了。 */
col[j] = col[j] ^ col[i];
}
}
Arrays.sort(col);
}
for(int i=0 ;i<n;i++)
if(col[i] !=0){
count ++;
}
System.out.println(count);
}
}
public static int highbit(int x){
/*一个数是由32位表示的,那么我们可以把一个数看成是32维空间的一个向量。最后形成了一个n*32的矩阵*/
for(int i=31;i>=0;i--)
{
//相同则结果为0,不同则结果为1
int m = (x>>i)&1;
if(m != 0)
return i+1;//找到高位,而不是i
}
return 0;
}
}
import java.io.*; import java.util.*; public class Main { public static void main(String[] args) { mixedColour(); } public static void mixedColour() { Scanner scanner=new Scanner(System.in); int num=scanner.nextInt(); Integer[] colour=new Integer[num]; int index=0; //注意不能写成 scanner.hasNextInt() && index<num,这样的话会先执行scanner.hasNextInt(),然后一直等待输入 while(index<num && scanner.hasNextInt()) { colour[index]=scanner.nextInt(); index++; } HashSet<Integer> allColour=new HashSet<Integer>(); int count=0; for(int i=0;i<colour.length;i++) { if(allColour.contains(colour[i])) { continue; } HashSet<Integer> tmpColour=new HashSet<Integer>(); tmpColour.add(colour[i]); for(int tmp:allColour) { tmpColour.add(tmp^colour[i]); } allColour.addAll(tmpColour); count++; if(allColour.containsAll(Arrays.asList(colour))) { System.out.println(count); break; } } } } 各位大神可以看看我这思路对吗?本地调试可以通过但是牛客网上超时,如果思路对的话有没有啥子优化方法呢?