题目叙述
问题描述:略
输入格式:略
输出格式:略
样例
样例1输入
6
0 0
1 0
1 1
3 1
5 1
7 1
样例1输出
3
样例2输入
8
5 1
5 0
5 0
2 1
3 0
4 0
100000000 1
1 0
样例2输出
100000000
满分证明
解题思路
问题描述有点复杂,如果用暴力穷举会超时(只能得70分,┭┮﹏┭┮),这时候就要想如何去优化了。
最近几年的CCF考试都有从描述复杂的现实问题中抽象出简单逻辑问题的趋势;比如该题为每一个阈值正确的个数与“resulti”有直接联系,而且用前缀和思想。
如果大家之前学过前缀和思想,那这道题就很简单了(没学过的小伙伴可以点击下方的参考链接,我觉得另外一名博主讲的挺好的)。
前缀和是一种重要的预处理,能大大降低查询的时间复杂度。
- 前缀和是在有序数组的基础上进行;
- 在进行完排序,分别计算截止到每一个“yi”的正确次数(本题考查核心);
- 依次遍历每个阈值,寻找最大预测次数(最大预测次数=该阈值前0的个数+该阈值后1的个数);
- 注意遇到两个阈值相等,取最大的(通过在判断时多写一个等号即可)。
注意:
我在调试程序时发现一个问题,对排序后的list去重,变成集合后,集合并不是有序的!!!
a = [1, 4, 8, 7, 10000000, 4, 5, 4, 8]
a.sort()
print(set(a))
>>
{10000000, 1, 4, 5, 7, 8}
满分代码
m = eval(input())
yr = []
# 计算1出现的总次数
ones = 0
for _ in range(m):
yi, ri = map(int, input().split())
yr.append([yi, ri])
if ri == 1:
ones = ones + 1
# 对yr依据yi排序
yr.sort(key=lambda x: x[0])
oy = list(a[0] for a in yr)
ss = set()
acc_sum = [0 for _ in range(m)]
acc_sum[0] = yr[0][1]
f_t = 0
bes_res = 0
for i in range(1, m):
acc_sum[i] = acc_sum[i - 1] + yr[i][1]
for ind, y in enumerate(oy):
if y not in ss:
ss.add(y)
tem = sum[ind - 1]
res = ind - tem + ones - tem
if res >= bes_res:
bes_res = res
f_t = y
print(f_t)
感谢及参考博文
部分内容参考以下链接,这里表示感谢 Thanks♪(・ω・)ノ
参考博文1 前缀和(一)
https://blog.youkuaiyun.com/fgy_u/article/details/109349710
参考博文2 前缀和(二)
https://blog.youkuaiyun.com/FGY_u/article/details/109390559
需者自取传送门(∩ᄑ_ᄑ)⊃━☆【CCF 2013-2021】本博主整理历年至少前两题 python 满分代码目录