The Travelling Customer (Coding, Training)
题目描述
In this programming challenge you need to solve the following problem:
You are represented a pricelist, an itemamount and a sum, as well as the stock parameter.
Your job is to select itemamount items which will result in the sum.
You may not select more items than stock from each type.Example:
Chips=4
Eggs=2Items=5
Sum=14
Stock=3
Level=1An accepted answer would be: 2Chips3Eggs
Visit problem.php to request a new problem.
Send your answers to [answer.php?answer=answer] with the format NItemnameNItemname.
You need to solve 5 problems and your timelimit for each problem is 3 seconds.Good Luck!
在这个编程挑战中你需要解决如下问题:
你将看到一个pricelist、一个itemamount和一个sum,以及stock参数。
你的工作是选出结果为sum的tiems的itemamount。
你选出的每种类型的itemamount不能超过stock
例子:
Chips = 4
Eggs = 2
Items = 5
Sum = 14
Stock = 3
Level = 1
一种承认的答案是:2Chips3Eggs
访问 problem.php 来请求一个新问题。
将你的答案以NItemnameNItemname的格式发送到answer.php?answer=[answer]
你需要解决5道题,每道题的时间限制为3秒。
祝你好运!
解
似乎是一个背包问题,但是这里已经给出最大价值,变成了一个约束求解的问题,解题思路很清楚,从problem.php得到数据,然后解出答案提交到answer.php,只不过有3秒的时间限制,手速快点还是有机会的,我手速比较慢,就写一个脚本代劳了。
这里使用的是Z3约束求解器来完成的,只需要定义好未知数(x),添加好约束条件(0<x<Stock, sum(x) == items, sum(x*pricelist(x)) == sum)即可快速解出未知数(如果有解的话),然后提交结果即可
直接上代码(每一个print都是一个学习的点啊!),
from z3 import *
import requests
def SolveProblem():
exec(ProblemResult.text)
problemdata = locals()
#print(problemdata)
items = problemdata['Items']
sum = problemdata['Sum']
stock = problemdata['Stock']
level = problemdata['Level']
problemdata.pop('Items')
problemdata.pop('Sum')
problemdata.pop('Stock')
problemdata.pop('Level')
#print(problemdata)
s = Solver()
key = list(problemdata.keys())
value = [problemdata[i] for i in key]
x = [Int('x%d' %i) for i in range(len(problemdata))]
#print(value)
#print(x)
for i in range(len(x)):
s.add(x[i] < stock)
s.add(x[i] > 0)
#个人感觉这里可以优化,但是没去深入研究
if level == 1:
s.add(x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] == items)
s.add(value[0]*x[0] + value[1]*x[1] + value[2]*x[2] + value[3]*x[3] + value[4]*x[4] + value[5]*x[5] + value[6]*x[6] + value[7]*x[7] == sum)
if level == 2:
s.add(x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] + x[8] == items)
s.add(value[0]*x[0] + value[1]*x[1] + value[2]*x[2] + value[3]*x[3] + value[4]*x[4] + value[5]*x[5] + value[6]*x[6] + value[7]*x[7] + value[8]*x[8] == sum)
if level == 3:
s.add(x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] + x[8] + x[9] == items)
s.add(value[0]*x[0] + value[1]*x[1] + value[2]*x[2] + value[3]*x[3] + value[4]*x[4] + value[5]*x[5] + value[6]*x[6] + value[7]*x[7] + value[8]*x[8] + value[9]*x[9] == sum)
if level == 4:
s.add(x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] + x[8] + x[9] + x[10] == items)
s.add(value[0]*x[0] + value[1]*x[1] + value[2]*x[2] + value[3]*x[3] + value[4]*x[4] + value[5]*x[5] + value[6]*x[6] + value[7]*x[7] + value[8]*x[8] + value[9]*x[9] + value[10]*x[10] == sum)
if level == 5:
s.add(x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7] + x[8] + x[9] + x[10] + x[11] == items)
s.add(value[0]*x[0] + value[1]*x[1] + value[2]*x[2] + value[3]*x[3] + value[4]*x[4] + value[5]*x[5] + value[6]*x[6] + value[7]*x[7] + value[8]*x[8] + value[9]*x[9] + value[10]*x[10] + value[11]*x[11] == sum)
solution = []
answer = ''
if s.check() == sat:
m = s.model()
for i in range(len(x)):
solution.append(m[x[i]].as_long())
answer += str(solution[i])+key[i]
#print(level,answer)
return answer
ProblemUrl = 'http://www.wechall.net/challenge/training/programming/knapsaak/problem.php'
AnswerUrl = 'http://www.wechall.net/challenge/training/programming/knapsaak/answer.php'
cookie = {}#用你自己的Cookie
ProblemResult= requests.post(url=ProblemUrl,cookies=cookie)
#print(ProblemResult.text)
Answer = SolveProblem()
#print(Answer)
AnswerUrl += '?answer=['+Answer+']'
AnswerResult = requests.post(url=AnswerUrl,cookies=cookie)
print(AnswerResult.text)
只需要用自己的Cookie运行5次脚本即可解题(个人感觉还能优化,不过懒得弄了)。