MilkShakes,这道题有些难度,自己水平太差,还没有找到好的方法来解决。对于small case,得到了正确的答案。先来看看题。
题目的大概意思是,给一些不同flavor(风味)牛奶(1,..N),可以是malted(1),也可以是unmalted(0),但是每一种牛奶只能是malted或者unmalted;有很多顾客,每个顾客喜欢的不一样,也可能喜欢多种。要求给出各种牛奶是否malted,能够满足所有顾客都有自己喜欢的flavor,并且malted的数量尽可能少。具体内容参考http://code.google.com/codejam/contest/32016/dashboard#s=p1
最直接的方法就是产生0,1的序列,检查是否满足。为了使malted的数量尽可能少,所以产生0,1序列的顺序是里面的1从少到多。基于这个想法,有了下面的程序实现。
#!/usr/bin/python
#encoding:UTF-8
#Filename:MilkShakes.py
import sys
def checkSatisfy(customer,choice):
for i in range(customer[0]):
j = 2 * i + 1
if choice[customer[j]-1]==customer[j+1]:
return 1
return 0
def binary2dec(binaryArray):
var = 0
for i in range(len(binaryArray)):
if binaryArray[i]==1:
var = var + (binaryArray[i]<<i)
return var
def generateFlavorArray(binaryNum):
# binaryNum = 4
initial = [];
for i in range(binaryNum):
initial.append(0)
layer0 = [initial]
layer1 = []
record = {}
cnt = 0
record[binary2dec(initial)] = cnt
flavorArray = [initial]
while(len(layer0)>0):
for i in range(len(layer0)):
tmp = layer0[i]
for j in range(binaryNum):
tmp1 = tmp[0:]
if tmp1[j]==0:
tmp1[j] = 1
if binary2dec(tmp1) not in record:
layer1.append(tmp1)
cnt = cnt + 1
record[binary2dec(tmp1)] = cnt
# print tmp1
flavorArray.append(tmp1)
layer0 = layer1
layer1 = []
return flavorArray
inname = "input.txt"
outname = "output.txt"
if len(sys.argv)>1:
inname = sys.argv[1]
outname = inname.rstrip(".in")
outname = outname + ".out"
fin = open(inname,"r")
fout = open(outname,"w")
line = fin.readline()
testCaseNum = int(line)
caseNum = 0
for caseNum in range(testCaseNum):
line = fin.readline()
flavorNum = int(line)
line = fin.readline()
customerNum = int(line)
# lines = fin.readlines(customerNum)
customers = []
# for line in lines:
for i in range(customerNum):
line = fin.readline()
line = line.rstrip("\n")
customer = [int(val) for val in line.split()]
# print customer
customers.append(customer)
customers.sort()
answer = "Case #%d:" %(caseNum+1)
flavorArray = generateFlavorArray(flavorNum)
flag = 0
for choice in flavorArray:
customerCnt = 0
for customer in customers:
if checkSatisfy(customer,choice)!=1:
break
customerCnt = customerCnt + 1
if customerCnt == customerNum:
an = [" "+str(b) for b in choice]
for s in an:
answer = answer + s
answer = answer + "\n"
flag = 1
break
if flag==0:
answer = answer + " IMPOSSIBLE\n"
fout.write(answer)
fin.close()
fout.close()
这个程序测试small case的时候还可以通过,测试large case的时候占用内存太大。这种穷据搜索的方法不太合适,需要找一个更好的算法。
接下来会考虑贪心算法,或者其他的,希望能找到有效的方法。