笔试时候没做得太好,结束了重新做一遍,刷题还是不能停啊QAQ。
题目描述
在你的面前从左到右摆放着n根长短不一的木棍,你每次可以折断一根木棍,并将折断后得到的两根木棍一左一右放在原来的位置(即若原木棍有左邻居,则两根新木棍必须放在左邻居的右边,若原木棍有右邻居,新木棍必须放在右邻居的左边,所有木棍保持左右排列)。折断后的两根木棍的长度必须为整数,且它们之和等于折断前的木棍长度。你希望最终从左到右的木棍长度单调不减,那么你需要折断多少次呢?
输出描述
第一行是一个数n,表示开始时有多少根木棍(1<=n<=3000)第二行有n个数,从第1个到第n个分别表示从左到右的木棍长度。对任意木棍的长度l,有1<=l<=3000。
输出一行,一个数,你最少所需的折断木棍的次数x
示例1
输入:
5
3 5 13 9 12
输出
1
考试时提交版本:(没有ac,有的情况没有考虑到)
#coding=utf-8
import sys
if __name__ == "__main__":
result = 0
n = int(sys.stdin.readline().strip()) #输入数组长度n
line = sys.stdin.readline().strip() #输入数组
values= list(map(int,line.split())) #转为list
while 1:#循环直至单调不减
#判断是否单调不减
c = values.copy()
c.sort()
if c == values:
break
#开始遍历
i = 0
while 1:
if i >= len(values)-1:
break
# 如果有不符合规则的木棍直接对折
if not values[i] <=values[i+1]:
#奇数的话小的放左边大的放右边
values.insert(i, values[i]//2)
values[i+1]=values[i+1]-values[i]
#折断次数+1
result = result +1
continue
i = i+1
print(result, values)
从头遍历时间复杂度过高,修改为从尾部开始遍历,只需要遍历一次
#coding=utf-8
import sys
if __name__ == "__main__":
result = 0
n = int(sys.stdin.readline().strip())
line = sys.stdin.readline().strip()
values= list(map(int,line.split()))
r = [values[-1]] #创建单调不增栈
values.pop(-1) #从尾部开始遍历
while values:
tmp = values[-1]
#如果没有折完当前木棍
while tmp:
#符合规则直接入栈
if tmp <= r[-1]:
r.append(tmp)
tmp = 0
#如果有不符合规则的木棍直接对折
else:
#对折后小于栈顶
if int(tmp/2+0.5) <=r[-1]:
r.append(int(tmp/2+0.5))
#对折后仍然大于栈顶
else:
r.append(r[-1])
tmp = tmp - r[-1]
result=result+1
values.pop(-1)
print(r,result)