题目概述:
解题思路:
题目的描述虽然看起来较为复杂,需要抽象成一个简单的任务。就拿样例一的输入作为例子分析:
- 当阈值选择为1时,看<1的数 中有多少个的 是为0的,>=1中有多少 为1的 不难知 <1的数中有1个 为0,>=1的数中有4个 为1,满足条件的共有1+4=5
- 当阈值选择为3时,<3的数中有2个 为0,>=3的数中有3个 为1,满足条件的共有2+3=5
- 但由于题目要求当数量相同时,选y值更大的数,故选择3而不选择1
在这里进行一些思考:
- 会发现如果想要做到上述例子分析中的第一点,就需要 是递增排序的,因此在接收数据之后需要首先对其进行排序
- 若每次遍历一个 就需要从前往后计算一遍0和1的数量必定会导致超时,因此这里可以采用前缀和的思想来减少时间开销;【通过开设一个s[0][N]和s[1][N]数组来记录位于某一个位置时,前面有多少个0或多少个1】
- 前缀和基本公式为 故我们需要从下标1开始操作,以免出现数组越界问题
满分代码:
"""
接收数据
"""
m = int(input())
y = []
result = []
for i in range(m):
yi, resulti = map(int, input().split())
y.append(yi); result.append(resulti)
"""
排序
"""
sort_data = sorted(zip(y,result))
"""
排序完后重新放回新的列表中
"""
y_new = [0]
result_new = [0]
for yi, resulti in sort_data:
y_new.append(yi); result_new.append(resulti)
"""
准备空的二维列表s并分别计算0和1的前缀和
"""
s = [[0 for _ in range(100010)]for _ in range(2)]
for i in range(2):
for j in range(1,m+1):
s[i][j] = s[i][j-1] + (result_new[j] == i) # 这个(result_new[j] == i)巨妙无比
"""
遍历每个yi并找出最大值【注意当yi相同时需要跳过】
"""
max = -1; cnt = 0; res = 0
for i in range(1,m+1):
if y_new[i] == y_new[i-1]:
continue
cnt = s[0][i-1] + s[1][m] - s[1][i-1]
if cnt >= max:
max = cnt
res = y_new[i]
print(res)