算法刷题之蓝桥杯2022年第十三届省赛真题-重新排序 python解法

先附上题目链接:
https://www.dotcpp.com/oj/problem2690.html

题目

题目描述
给定一个数组 A 和一些查询 Li , Ri,求数组中第 Li 至第 Ri 个元素之和。

小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少?

输入格式
输入第一行包含一个整数 n。

第二行包含 n 个整数 A1, A2, · · · , An,相邻两个整数之间用一个空格分隔。

第三行包含一个整数 m 表示查询的数目。

接下来 m 行,每行包含两个整数 Li、Ri ,相邻两个整数之间用一个空格分隔。

输出格式
输出一行包含一个整数表示答案。
样例输入
5
1 2 3 4 5
2
1 3
2 5
样例输出
4
提示
原来的和为 6 + 14 = 20,重新排列为 (1, 4, 5, 2, 3) 后和为 10 + 14 = 24,增加了 4。

对于 30% 的评测用例,n, m ≤ 50 ;

对于 50% 的评测用例,n, m ≤ 500 ;

对于 70% 的评测用例,n, m ≤ 5000 ;

对于所有评测用例,1 ≤ n, m ≤ 105,1 ≤ Ai ≤ 106,1 ≤ Li ≤ Ri ≤ 106 。

代码

先贴自己写的,经典小题大做,,21个样例超时了6个,,

n=int(input())
k=input().split()
for i in range(n):
     k[i]=int(k[i])
t=[0]*(n+1)
u=[]
m=int(input())
yuan=0
for i in range(m):
     w=input().split()
     for i in range(int(w[0]),int(w[1])+1):
          t[i]+=1
     u.append(int(w[0]))
     u.append(int(w[1]))
     yuan+=sum(k[int(w[0])-1:int(w[1])])
dic={}
k.sort()
k.reverse()
for i in range(1,n+1):
     dic[i]=t[i]
dic=sorted(dic.items(),key=lambda x:x[1],reverse=True)
#print(dic)
a=[0]*(n+1)
cnt=0
ans=0
while(cnt<n):
     a[dic[cnt][0]]=k[cnt]
     cnt+=1
for i in range(m):
     ans+=sum(a[u[2*i]:u[2*i+1]+1])  
print(ans-yuan)

看了优质题解后换了一种方法,简化了代码,结果还是超时了3个TAT,python真是太容易超时了:

n=int(input())
k=input().split()
for i in range(n):
     k[i]=int(k[i])
cnt=[0]*(n+2)
dif=[0]*(n+2)
m=int(input())
yuan=0
for i in range(m):
     w=input().split()
     dif[int(w[0])]+=1
     dif[int(w[1])+1]-=1
for i in range(1,n+1):
    cnt[i]=cnt[i-1]+dif[i]
cnt=cnt[1:n+1]
for i in range(n):
     yuan+=cnt[i]*k[i]
k.sort()
cnt.sort()
ans=0
for i in range(n):
     ans+=cnt[i]*k[i]
print(ans-yuan)
          

你可能感兴趣的:(算法,蓝桥杯,算法,python)