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的時候佔用記憶體太大。這種窮據搜尋的方法不太合適,需要找一個更好的演算法。
接下來會考慮貪心演算法,或者其他的,希望能找到有效方法。