一个在实际工作中遇到的算法问题,比较基础,求教。

2014-07-30 16:40:03 +08:00
 MarioLuisGarcia
有一个长度为n的列表,代表某物品的价格。

玩家第一次购买该物品时,花费的价格是列表第一项的价格。依此类推,到第n次,花费的是列表第n项的价格。

从第n+1次开始,每次购买花费的都是列表第n项的价格。

在一个购买行为里,玩家可以购买多项该物品,如,购买次数为3。如该玩家是首次购买该物品,所花费的钱是列表第1,2,3项的总和。 如玩家在进行该购买行为时,已经买过n次了,那么该购买行为花费的金钱是3*n。

现在我们仅知道玩家一个购买行为里的购买次数x (不知道他之前买了多少次), 以及该购买所花费的金钱y. 我们需要求出该玩家这个购买行为里所花费的金钱组成(第一个购买次数花了多少钱,第二个花了多少钱,第x个购买次数花了多少钱)。

我已经想出应该怎么做,先看 x * 列表第n项 是否等于 y, 如果不等于,再看 (x-1) * 列表第n项 + 1 * 列表第n-1项 是否等于 y, 一直到 1* 列表第x项 + 1 * 列表第x-1项 + ... + 列表第1项 是否等于 y 即可

但是,发现要把这个想法表达成程序语言表达式,对我而言有些困难(用的python)

特此求教。
3133 次点击
所在节点    问与答
28 条回复
loryyang
2014-07-30 17:07:32 +08:00
除了遍历,其他无解吧。我的第一感觉是这样:

1. 对于固定的购买次数x,我们只需要过一轮数据,就可以知道起点为i的x次购买总价格是多少,也就是一个[i, y]对,i从0到n
2. 那么对于某个固定的y,从1的结果里面找到匹配项就行了。ps:匹配项可能会多于一个,这也是我感觉只能遍历的原因。

复杂度最简单是n*x,当然,你第一步可以稍微优化下,大概是个n+x的复杂度

想的不是很细致,LZ可以再看看
mingkaidox
2014-07-30 17:18:51 +08:00
这个可能有多解,比如当第n次和第n-1次买价格一样的时候,可能要注意下。
MarioLuisGarcia
2014-07-30 17:31:08 +08:00
@loryyang 怎么解大概想出来了,语言表达还在想。不过在提出这个问题后又狂想一阵,有个雏形了,测试中
MarioLuisGarcia
2014-07-30 17:31:36 +08:00
@mingkaidox 为什么会有多解的情况?不是很明白。
MarioLuisGarcia
2014-07-30 18:23:23 +08:00
@loryyang 好像可以实现了,不过方法有点dirty....
MarioLuisGarcia
2014-07-30 18:37:41 +08:00
我的解法(X = 次数,Y = 钱, L = 列表,写法是python)

T = 0
while True:
if X > T and T ==0:
if L[-1]*(X-T) == Y:
break
else:
T += 1
elif X > T and T >=1:
if L[-1]*(X-T) + sum(L[(-1)-i] for i in xrange(T+1) if i > 0):
break
else:
T += 1
elif X <= T:
if sum(L[(-1)-i] for i in xrange(T-X,T+1) ) == Y:
break
else:
T += 1
MarioLuisGarcia
2014-07-30 18:38:43 +08:00
indentation因为v2ex显示问题不对了。
MarioLuisGarcia
2014-07-30 18:40:06 +08:00
T = 0
while True:
if X > T and T ==0:
if L[-1]*(X-T) == Y:
break
else:
T += 1
elif X > T and T >=1:
if L[-1]*(X-T) + sum(L[(-1)-i] for i in xrange(T+1) if i > 0):
break
else:
T += 1
elif X <= T:
if sum(L[(-1)-i] for i in xrange(T-X,T+1) ) == Y:
break
else:
T += 1
MarioLuisGarcia
2014-07-30 18:40:27 +08:00
再试一次排版,还是失败了。。。
MarioLuisGarcia
2014-07-30 18:41:01 +08:00
T = 0
while True:
\ if X > T and T ==0:
MarioLuisGarcia
2014-07-30 18:41:28 +08:00
看来有点弄不明白怎么在v2ex 缩进了。。。。
qsl0913
2014-07-30 18:52:32 +08:00
L=[1,2,3,4,5,5,4,3,2,1,1,1,1]
X=5
Y=15
两个解
qsl0913
2014-07-30 18:53:18 +08:00
@MarioLuisGarcia markdown
MarioLuisGarcia
2014-07-30 18:56:14 +08:00
@qsl0913 看来md的学习优先度要提前了.
如果列表是递增的,即后一项一定大于或等于前一项,应该就不会出现你所说的情况了吧?
MarioLuisGarcia
2014-07-30 18:57:11 +08:00
@qsl0913 oh my god, 难道我要用&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;来缩进代码? @天!
MarioLuisGarcia
2014-07-30 19:06:17 +08:00
T = 0
while True:
if X > T and T ==0:
if L[-1]*(X-T) == Y:
break
else:
T += 1
elif X > T and T >=1:
if L[-1]*(X-T) + sum(L[(-1)-i] for i in xrange(T+1) if i > 0):
break
else:
T += 1
elif X <= T:
if sum(L[(-1)-i] for i in xrange(T-X,T+1) ) == Y:
break
else:
T += 1
MarioLuisGarcia
2014-07-30 19:06:36 +08:00
...从stackoverflow辅助过来也不行。。。
MarioLuisGarcia
2014-07-30 19:07:20 +08:00
T = 0
while True:
* if X > T and T ==0:
* if L[-1]*(X-T) == Y:
* break
*else:
* T += 1
* elif X > T and T >=1:
* if L[-1]*(X-T) + sum(L[(-1)-i] for i in xrange(T+1) if i > 0):
* break
*else:
* T += 1
* elif X <= T:
* if sum(L[(-1)-i] for i in xrange(T-X,T+1) ) == Y:
* break
*else:
* T += 1
wudikua
2014-07-30 19:07:48 +08:00
@MarioLuisGarcia ```code```
wudikua
2014-07-30 19:08:46 +08:00
`code`

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/125298

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX