[算法题]小朋友分糖问题
问题:现在有n个小朋友坐成一排,每个小朋友都有一个竞赛得分,现在要根据竞赛得分给小朋友分糖,要求是相邻坐着的小朋友,分数高的小朋友的糖要比分数低的小朋友糖多(小朋友是随机坐的,也就是分数没排序),相邻的两个小朋友分数如果相同,那么得到的糖也要相同,现在程序要给出最少需要多少糖。
输入要求:
- 第一行输入一共有几个小朋友
- 第二行输入每个小朋友的竞赛分数,用空格隔开每个分数。
如:
3
1 2 2
应该到得到输出:5
解释:糖的分配情况 1 2 2,因为第一个分数最低,他得到1,第二个比第一个分数高,所以得到的糖也要比第一个多所以是2,第三个和第二个分数相同,所以得到的糖也要相同,所以也是2。
4
3 5 5 2
应该得到输出:6
解释:糖的分配情况1 2 2 1,因为与第一个相邻的小朋友分数都要高于它,所以他的粮要最少所以是1,第二个比第一个分数高,所以也要多拿一颗糖,所以是2。第三个和第二个相同,所以也要是2。第个四的分数低于附近的小朋友,所以也是1,因为第4个并不与第1个小朋友是邻居,所以他们之间不参与比较。
8
2 4 3 5 2 6 4 5
应该得到输出:12
糖的分配情况:1 2 1 2 1 2 1 2
根据题目我的程序是:
def initArr(arr):
# -1代表没分配过
min_x = min(arr)
arr = [[x, 1 if x==min_x else -1] for x in arr]
return arr
def get_condition_id(position,arr)->int:
if position==len(arr)-1:
return 2#列表结尾
elif arr[position]==arr[position+1]:
return 3#和列表当前位置之后元素相同
elif position== 0:
return 0#列表开头
elif position!=0 and position!=len(arr)-1:
return 1#列表中间
def fun_0(cur_index,n,arr):#列表开头
if arr[n][0] < arr[n + 1][0]:
arr[n][1] = 1
elif arr[n][0] > arr[n + 1][0]:
arr[n][1] = get_candy_num(n+1,arr) + 1
return (cur_index,n)
def fun_1(cur_index,n,arr):#列表中间
if arr[n - 1][0] > arr[n][0] < arr[n + 1][0]:
arr[n][1] = 1
else:
if arr[n - 1][0] > arr[n][0] > arr[n + 1][0]:
arr[n][1] = get_candy_num(n+1,arr) + 1
elif arr[n - 1][0] < arr[n][0] < arr[n + 1][0]:
arr[n][1] = arr[n - 1][1] + 1
elif arr[n - 1][0] < arr[n][0] > arr[n + 1][0]:
arr[n][1] = max(arr[n - 1][1], get_candy_num(n+1,arr)) + 1
return (cur_index,n)
def fun_2(cur_index,n,arr):#列表结尾
if arr[n - 1][0] > arr[n][0]:
arr[n][1] = 1
if arr[n - 1][0] < arr[n][0]:
arr[n][1] = arr[n - 1][1] + 1
return (cur_index,n)
def fun_3(cur_index,n,arr):
#在这个函数里将相邻的相同元素视为一个元素
same_val_index=[]#保存相同元素索引
same_val_index.append(n)
while n+1 < len(arr) and arr[n][0]==arr[n+1][0]:
same_val_index.append(n+1)
n+=1
if same_val_index[-1] == len(arr)-1:#如果这是列表最后一位
if arr[same_val_index[0]-1][0] > arr[same_val_index[0]][0]:
for i in same_val_index:
arr[i][1]=1
else:
for i in same_val_index:
arr[i][1]=arr[same_val_index[0]-1][1]+1
else:
if arr[same_val_index[0]-1][0] > arr[same_val_index[0]][0] > arr[same_val_index[-1]+1][0] :
arr[same_val_index[0]][1]=get_candy_num(same_val_index[-1]+1,arr)+1
elif arr[same_val_index[0]-1][0] > arr[same_val_index[0]][0] < arr[same_val_index[-1]+1][0] :
arr[same_val_index[0]][1]=1
elif arr[same_val_index[0] - 1][0] < arr[same_val_index[0]][0] < arr[same_val_index[-1] + 1][0]:
arr[same_val_index[0]][1]=arr[same_val_index[0] - 1][1]+1
elif arr[same_val_index[0] - 1][0] < arr[same_val_index[0]][0] > arr[same_val_index[-1] + 1][0]:
arr[same_val_index[0]][1]=max(arr[same_val_index[0] - 1][1],get_candy_num(same_val_index[-1] + 1,arr)) + 1
for i in same_val_index:
arr[i][1] = arr[same_val_index[0]][1]
return (cur_index,n)
condition={
0:fun_0,#列表开头
1:fun_1,#列表中间
2:fun_2,#列表结尾
3:fun_3,#和列表当前位置之后元素相同
#和列表当前位置之前元素相同
}
def get_candy_num(n,arr)->int:
if arr[n][1] != -1: return arr[n][1]
cur_index=n
cur_index,n=condition[get_condition_id(n,arr)](cur_index,n,arr)
if arr[cur_index][1] != -1:
return arr[cur_index][1]
else:
return get_candy_num(n,arr)
def candies(n, arr):
# Write your code here
arr = initArr((arr))
tot_candies = 0
for i in range(n):
tot_candies += get_candy_num(i, arr)#f_allocate(i,arr)#
#with open(r'E:\practices\python\arr.json','w') as f:
# json.dump(arr,f)
return tot_candies
PS:我认为这个函数最难的地方就是怎么处理比邻相同积分的小朋友。这个程序很臃肿,一时还想不到优化的方法