方法1: 暴力,把每个阈值和m个条目进行判断,计数。只能过70%的用例
方法2: 统计一个阈值预测准确的数量并不需要一个个判断的嘛,小于该阈值的分数,对应结果要是0(挂)才算正确;大于等于该阈值的分数,对应结果要是1(过)才算正确。所以可先用字典统计每个阈值挂了的(0)和过了的(1)数量,然后按分数大小排序(这一步已经去重复了)。计算阈值正确数的时候,从该阈值开始,往低分处走统计0的数量,往高分处走统计1的数量,最后加一起。
每算一个阈值的正确率,就要往高低走统计,这样复杂度也是O(n^2),和暴力没区别。不过稍微改一下,就马上变O(n)。往高低走统计数量的时候其实有很多重复了的,比如有阈值[1,3,5,7],统计7的0的数量时候,往低处算要算上1,3,5的总数,统计5的时候,又要往前统计1,3的,重复很多,我们可以从1开始统计好总数记下来,3的时候用前面1的总数累加3自己的数,到5的时候,用3的累加5的数,就不用往前走了。 我们可以先用数组存好到达每个阈值的0的总数,计算某个阈值的0的总数时只需要用前面的总数加上本身0的数量即可,是一种动态规划。1同理,不过是从高分处开始计算。这样事先把每个阈值的低处0的总数和高处1的总数算出来后,就不用在计算某阈值准确率时往高低两边走,直接从数组中找到结果计算。 我这里直接在字典里加上变量了,没有用数组。
d = {}
m = int(input())
for i in range(m):
y, res = map(int, input().split())
if y in d:
d[y][res] += 1
else:
# d[y]中,4个位置分别是
# 挂了的数量,过了的数量,
# 低分到这里的挂了的总数量,这里到高分的过了的数量
d[y] = [0, 0, 0, 0]
d[y][res] += 1
best, best_cnt = 0, 0
keys = sorted(d) # 阈值升序排序
# 初始化头尾
d[keys[0]][2] = d[keys[0]][0]
d[keys[-1]][3] = d[keys[-1]][1]
# 累计,到该分数段,挂了的数量
for idx in range(1, len(keys)):
key, pre_key = keys[idx], keys[idx - 1]
d[key][2] = d[pre_key][2] + d[key][0]
# 累计,到该分数段,过了的数量
for idx in range(len(keys) - 2, -1, -1):
key, pre_key = keys[idx], keys[idx + 1]
d[key][3] = d[pre_key][3] + d[key][1]
# 计算每个阈值预测正确率,选出答案
for idx in range(len(keys)):
key, pre_key = keys[idx], keys[idx - 1]
# 小于该阈值的分数要0才是正确,大于等于的则1才正确
cnt = d[key][2] - d[key][0] + d[key][3]
if cnt > best_cnt:
best_cnt = cnt
best = key
elif cnt == best_cnt and key > best:
best = key
print(best)
# 7
# 0 0
# 1 0
# 1 0
# 1 0
# 3 0
# 5 0
# 7 0