网易笔试——混合颜料
你就是一個畫家!你現在想繪制一幅畫,但是你現在沒有足夠顏色的顏料。為了讓問題簡單,我們用正整數表示不同顏色的顏料。你知道這幅畫需要的n種顏色的顏 料,你現在可以去商店購買一些顏料,但是商店不能保證能供應所有顏色的顏料,所以你需要自己混合一些顏料。混合兩種不一樣的顏色A和顏色B顏料可以產生 (A XOR B)這種顏色的顏料(新產生的顏料也可以用作繼續混合產生新的顏色,XOR表示異或操作)。本著勤儉節約的精神,你想購買更少的顏料就滿足要求,所以兼職 程序員的你需要編程來計算出最少需要購買幾種顏色的顏料?
輸入描述:
第一行為繪制這幅畫需要的顏色種數n (1 ≤ n ≤ 50) 第二行為n個數xi
(1 ≤ xi
≤ 1,000,000,000),表示需要的各種顏料.輸出描述:
輸出最少需要在商店購買的顏料顏色種數,注意可能購買的顏色不一定會使用在畫中,只是為了產生新的顏色。輸入例子:
3 1 7 3輸出例子:
3解題思路:
由于a^b=c那么a^c=b,a^a=0,最早的思路是將colors[]數組里的元素及其^的所有可能值全部放到一個Map里,然后找到Map里的最小不相交子集(就是里面的任何一個元素不能由其他元素通過^生成),但是后來發現空間復雜度都在O(Nn)。
后來發現一條規律,就是0001,0010,0100,1000,可以通過^生成任意4位的數字,那么本題的答案不會超過32(int的長度)
再后來想到高斯消元和最小線性無關組就有了自己的思路。首先將數組排序,獲取最高位的1,每次將最高位的1進行^運算,使得數組里面從后往前數最高位每個1只保留一個,最終得到類似于{0,0,00000001,00000011,00011000,00100010}這樣的結構,那么答案就出來了。
Java實現:
package com.tonyluis;import java.util.*;public class NeteaseSolution3 {public static void main(String[] args) {// TODO Auto-generated method stubScanner in = new Scanner(System.in);while (in.hasNext()) {final int SUM = in.nextInt();int[] colors = new int[SUM];for (int i = 0; i < SUM; i++)colors[i] = in.nextInt();Arrays.sort(colors);System.out.println(minColor(colors));}}static int minColor(int[] colors) {int max = 1 << 30;int right = colors.length - 1;while (right >= 0 && colors[right] != 0) {while (max > colors[right])max >>= 1;while (right > 0 && colors[right - 1] >= max) {colors[right - 1] ^= colors[right];insertSort(colors, right - 1);}right--;}return right >= 0 ? colors.length - right - 1 : colors.length;}// 將一個數插入到有序數組中 ArrayList底層使用數組實現,不如直接使用數組// 使用LinkedList可以減少直接插入排序的移位操作static void insertSort(int[] nums, int index) {int temp = nums[index];if (temp <= nums[0]) {for (int i = index; i > 0; i--)nums[i] = nums[i - 1];nums[0] = temp;return;}for (int i = index - 1; i >= 0; i--) {if (temp > nums[i]) {for (int j = index; j > i + 1; j--)nums[j] = nums[j - 1];nums[i + 1] = temp;return;}}} }?
?
轉載于:https://www.cnblogs.com/tonyluis/p/5774700.html
總結
以上是生活随笔為你收集整理的网易笔试——混合颜料的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Swift学习------常量与变量
- 下一篇: PHP-FPM进程数的设定