问题描述
有一个长度为n的数组(n是10的倍数),每个数ai都是区间[0,9]中的整数。小明发现数组里每种数出现的次数不太平均,而更改第i个数的代价为bi,他想更改若干个数的值使得这10个数出现的次数相等(都等于 ),请问代价和最少为多少。
输入格式
输入的第一行包含一个正整数n。
接下来的n行,第i行包含两个整数ai,bi,用一个空格分隔
输出格式
输出一行包含一个正整数表示答案。
样例输入
10
1 1
1 2
1 3
2 4
2 5
2 6
3 7
3 8
3 9
4 10
样例说明
只更改第1,2,4,5,7,8个数,需要花费代价1+2+4+5+7+8=27
评价用例规模与约定
对于20%的测评用例,n<=1000;
对于所有的测评用例,n<=,0<bi<=2*
思路讲解
一共是有n个数,每个数在0-9之间,要求0-9每个数在数组里出现的次数相等,即要把数组变成个0,个1,个2,个3,个4,个5,个6,个7,个8,个9。
对于0-9之间的每个数,可以统计用一个数组他们在数组里面出现的次数,再用一个字典统计该数字在每个数ai的修改代价。具体初始化形式如下:
n = int(input())
s = dict() #定义一个字典,统计0-9每个数字的修改代价,字典的键是数字,值是一个列表,因为一个数字出现了多次会有多个代价
s2 = [0 for i in range(10)] #定义一个数组,记录0-9每个数字出现的次数
for i in range(n):
a,b = map(int,input().split())
if a not in s:
s[a] =[b]
else:
s[a].append(b)
s2[a]+=1
遍历包含每个数字出现的次数的数组s2,s2[j]表示数字j出现的次数,j的值在0-9之间,此时分三种情况,一种是这个数字出现的次数<,一种是这个数字出现的次数=,一种是这个数字出现的次数>。
1.如果s2[j]<,则表示数字j出现的次数不满足要求,应该由别的数字变为数字j,即数组中为数字j的数不用发生改变。
2.如果s2[j]=,则表示数字j出现的次数已满足要求,数组中为数字j的数也不用发生改变。
3如果s2[j]>, 则表示数字j出现的次数不满足要求,应该将数组中的部分等于数字j的元素改为其他元素,具体改变成什么数字不用管,因为修改成其他任意数字的代价都是一样的。
至此,只有第三种情况才需要对数组a进行修改,若k = s2[j]-,即只需要将数组里面的k个为j数修改成别的数字即可,因为之前存储过数组中值为数字j的每个数的代价,只需要在里面取最小的k个求和即可。
num=0
for i in range(10):
if s2[i]>n//10:
k = s2[i]-n//10
s3 = sorted(s[i])
num+=sum(s3[:k])
完整代码
最后附上完整代码
import os
import sys
# 请在此输入您的代码
n = int(input())
s = dict()
s2 = [0 for i in range(10)]
for i in range(n):
a,b = map(int,input().split())
if a not in s:
s[a] =[b]
else:
s[a].append(b)
s2[a]+=1
num=0
for i in range(10):
if s2[i]>n//10:
k = s2[i]-n//10
s3 = sorted(s[i])
num+=sum(s3[:k])
print(num)
官网原题地址