首页 > 试题广场 >

混合颜料

[编程题]混合颜料
  • 热度指数:12836 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
你就是一个画家!你现在想绘制一幅画,但是你现在没有足够颜色的颜料。为了让问题简单,我们用正整数表示不同颜色的颜料。你知道这幅画需要的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
n = int(input().strip())
x_lst = list(sorted(list(map(int, input().strip().split())), reverse=True))
flag = 0 for i in range(len(x_lst)): if x_lst[i] == 0:
        flag = 1  print(i) for j in range(i + 1, len(x_lst)):
        x_lst[j] = min(x_lst[j], x_lst[i] ^ x_lst[j])
    x_lst = x_lst[0: i + 1] + list(sorted(x_lst[i + 1:], reverse=True)) if flag == 0: print(len(x_lst))
发表于 2019-03-01 18:19:23 回复(0)
'''
    说明:以下代码和思路均是参考各位大神,
    本人只做了额外的总结和解释,帮助大家理解。
    
    问题理解:
    输入n个数,将这些数之间进行多次xor(异或操作),
    其中一个数可能被xor多次,看最后能剩余多少不重复的数,输出数量即可。
    
    思路:
    类似矩阵求秩:首先将各数从大到小排序,
    对位数与该行相同的进行异或操作,操作结束后该行就“独立”了。
    
    具体过程如下:
        排序 i=0      异或      排序 i=1    异或
    101010 --> 111010 --> 111010 --> 111010 --> 
    111010 --> 110110 --> 001100 --> 010111 --> 
    101101 --> 101101 --> 010111 --> 010000 --> 
    110110 --> 101010 --> 010000 --> 001100 --> 

        排序 i=2   排序 i=3    排序 i=4 end     
    111010 --> 111010 --> 111010 --> 111010     
    010111 --> 010111 --> 010111 --> 010111     
    000111 --> 001100 --> 001100 --> 001100     
    001100 --> 000111 --> 000111 --> 000111     
    '''

# 求数字转化为2进制后的位数
def getHiBit(n):
    ans = 0
    while n:
        ans += 1
        n >>= 1
    return ans

n = int(input())
colors = list(map(int, input().split()))
colors.sort(reverse=True) # 从大到小排序
i = 0
while i<n and colors[i]:
    hibit = getHiBit(colors[i])
    for j in range(i+1, n):
        if getHiBit(colors[j])==hibit:
            colors[j] ^= colors[i]
        else: break
    colors.sort(reverse=True)
    i += 1
print(i)

编辑于 2018-08-07 16:30:28 回复(0)
#n个十进制的数转换成n个二进制的包含1,0的字符串,将每个数转换成二进制之后单成一行,位数小的前面被补全0
#这样这n个数就变成了n行矩阵,由于1 ≤ xi ≤ 1,000,000,000,而2的30次幂是10亿多
#所以这个矩阵最大是n*30的矩阵,然后进行行与行之间的xor,其中1^1=0;  0^0=0;  1^0=1; 0^1=1;
#这种运算很像求矩阵的秩,相同的相减为0,不同的相减为1.
#矩阵的秩定义:是其行向量或列向量的极大无关组中包含向量的个数。
#矩阵的秩求法:用初等行变换化成梯矩阵, 梯矩阵中非零行数就是矩阵的秩.
#所以这道题就被转化成了求矩阵的秩

def getHiBit(n):#求该数二进制最高位是几位
    ans = 0
    while n:
        ans += 1
        n >>= 1
    return ans

n=int(input())
x=sorted(list(map(int,input().split())),reverse=True)#倒序排列
r= 0
while r<n and x[r]:#r和i分别指向最大数和次大数
    hibit = getHiBit(x[r])
    for i in range(r+1, n):
        if getHiBit(x[i])==hibit:#最高位相同,那么一定可以消去
            x[i] ^= x[r]#i指向经过异或操作得到的新的数
        else: 
            break
    x.sort(reverse=True)#重新排序
    r += 1#经过一轮循环,所有数的最高位已经只有最大数是 1 了,这样它已经不可能被消掉了,结果+ 1
print(r)

发表于 2018-06-27 13:08:07 回复(0)
参照 夕阳Code,程序工匠0_0小姐思路
def getHiBit(n):
    ans = 0
    while n:
        ans += 1
        n >>= 1
    return ans
n = int(input())
colors = list(map(int, input().split()))
colors.sort(reverse=True)
i = 0
while i<n and colors[i]:
    hibit = getHiBit(colors[i])
    for j in range(i+1, n):
        if getHiBit(colors[j])==hibit:
            colors[j] ^= colors[i]
        else: break
    colors.sort(reverse=True)
    i += 1
print(i)  

编辑于 2017-10-08 21:48:02 回复(0)
def get_n(x):
    n = 0
    while x:
        x = x >> 1
        n += 1
    return n


def main():
    N = int(input())
    nums = [int(x) for x in input().split()]

    for j in range(N - 1):
        nums[j:] = sorted(nums[j:], reverse=True)
        y = nums[j]
        n_y = get_n(y)
        i = j+1
        while i < N and get_n(nums[i]) == n_y:
            nums[i] ^= y
            i += 1
    return N - nums.count(0)


print(main())
发表于 2017-09-22 20:43:37 回复(0)
def ghp(n):
	c=0;
	while n!=0:
		n>>=1
		c+=1
	return c
n=input()
a=raw_input().split()
a=[int(i) for i in a]
a.sort()
t=n-1
h=t-1
r=0
while len(a)>2:
	if ghp(a[t])==ghp(a[h]):
		temp=a[t]^a[h]
		if not(temp in a):
			a.append(temp)
			a.sort()
			t+=1
			h+=1
	else:
		r+=1
	a.pop()
	t=h
	h-=1
print r+len(a)

发表于 2017-08-13 11:23:13 回复(0)