Problem Statement for MixingColors | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
SRM621 1000分 第3题算法解答_____________________________________________________________________________
看了算法解释,真心佩服,自己数学融汇贯通的能力差啊。当时怎么也想不出来。
数学原理:求rank,即通过最大线性无关组获得,计算机解法,高斯消元法(Gauss Elimination)
矩阵A的秩=rank(A) = rank({A1,A2, .... Am});
每一个数字,都可以表示为一个二进制向量,如3={0,1,1},向量的纬度 m = 最大数的位数(直接用32也可以)
以{3,5,6}为例:
于是:矩阵A = {3,5,6} =
0 1 1
1 0 1
1 1 0
采用高斯消元法:注,这个时候的消元不是通过线性加减,而是异或准则
0 1 1
1 0 1
1 1 0
选择主行(即第A(0,0)!=0即可)交换
1 1 0
0 1 1
1 0 1
第0行与第2行异或——》第2行
1 1 0
0 1 1
0 1 1
第1行与第二行异或
1 1 0
0 1 1
0 0 0
于是,对角线上不为0的个数= rank(A)=2,所以答案为2
import java.util.*; /** * User: Free * Date: 14-5-20 * Time: 下午11:51 */ public class MixingColors { public int minColors(int[] colors) { int len = colors.length; Arrays.sort(colors); int max = 1; int maxCount = 31; maxCount = Integer.toBinaryString(colors[colors.length - 1]).length(); int i = 0; byte[][] A = new byte[colors.length][maxCount]; for (; i < colors.length; i++) { String bits = Integer.toBinaryString(colors[i]); for (int j = 0; j < bits.length(); j++) { A[i][maxCount - bits.length() + j] = (byte) (bits.charAt(j) - '0'); } for (int j = 0; j < maxCount - bits.length(); j++) { A[i][j] = 0; } } //gauss elimination // process Row =r,Col=c,A[r][c]==0 int r = 0; int c = 0; int pivot; for (r = 0; r < colors.length; r++) { do { if (c >= maxCount) break; for (pivot = r; pivot < colors.length; pivot++) { if (A[pivot][c] == 1) { break; } } if (pivot < colors.length) { //swap ROW pivot,r if (pivot != r) { for (int j = c; j < maxCount; j++) { byte t = A[pivot][j]; A[pivot][j] = A[r][j]; A[r][j] = t; } } //eliminate; for (int curRow = r + 1; curRow < colors.length; curRow++) { if (A[curRow][c] != 0) { //XOR for (int j = c; j < maxCount; j++) { A[curRow][j] ^= A[r][j]; } } } c++; break; } else { c++; } } while (true); } //calc rank(A) int rankRow = 0; for (int row = 0; row < A.length; row++) { for (int col = 0; col < A[0].length; col++) { if (A[row][col] != 0) { rankRow++; break; } } } return rankRow; } public static void main(String args[]) { MixingColors mix = new MixingColors(); System.out.println(mix.minColors(new int[]{4, 8, 16, 32, 64, 128, 256, 512, 1024})); // System.out.println(mix.minColors(new int[]{3, 5, 6})); // System.out.println(mix.minColors(new int[]{1, 3, 4, 5, 6, 8})); // System.out.println(mix.minColors(new int[]{534, 251, 76, 468, 909, 410, 264, 387, 102, 982, 199, 111, 659, 386, 151})); // // System.out.println(mix.minColors(new int[]{1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912})); } }