CCF 202012-2 期末预测之最佳阈值 python(100)
这道题对时间进行了限制,所以要想一次遍历得出结果,就应该思考!
样例输入
安全指数 | 0 | 1 | 1 | 3 | 5 | 7 |
---|---|---|---|---|---|---|
挂科情况 | 0 | 0 | 1 | 1 | 1 | 1 |
思路详解 <前提–安全指数升序排列>
- 首先令第一个同学的安全指数0为阈值E,计算此时预测正确的次数sum为4,最大正确次数max也为4,最佳阈值record为0。
- 循环下一个安全指数1为阈值E。比1大的安全指数和安全指数1在阈值E等于1和0时预测结果相同,所以不需要考虑。需要考虑比1小的前一或前几个相等的数,上例只需要考虑一个数0。如果阈值E=1预测安全指数为0的预测结果与其挂科情况一致,这说明阈值E=0时对其的预测结果错误,而此时正确,所以sum+1;反之阈值E=1预测安全指数为0的预测结果与其挂科情况不一致,这说明阈值E=0时对其的预测结果正确,而此时错误,所以sum-1。sum为5,max也为5,record为1。
- 循环下一个安全指数1为阈值E。阈值没有变化直接跳过。
- 循环下一个安全指数3为阈值E。需要考虑比3小的前一或前几个相等的数,上例需要考虑两个数1。因为两个同学的安全指数相同,挂科情况未必一致。而为什么不需要继续考虑安全指数更小的0?因为阈值E等于3或者1,对于0的预测结果相同,即影响效果相同,无须重复考虑。根据上面的思路,此时sum为5,max也为5,record为3。以此类推,即可!
Python源码
def predict(y, E):
if y >= E:
return 1
else:
return 0
def count(n, num_list, E):
sum = 0
for i in range(n):
if num_list[i][1] == predict(num_list[i][0], E):
sum += 1
return sum
if __name__ == '__main__':
n = int(input())
num_list = []
for i in range(n):
y, result = list(map(int, input().split()))
num_list.append([y, result])
num_list.sort(key=lambda num_list: num_list[0])
sum = count(n, num_list, num_list[0][0])
max = sum
record = num_list[0][0]
for j in range(1, n):
if num_list[j][0] > num_list[j - 1][0]:
z = j - 1
while True: # 需要考虑小于num_list[j][0]的前面几个数
if predict(num_list[z][0], num_list[j][0]) == num_list[z][1]:
sum += 1
else:
sum -= 1
if z-1 < 0 or num_list[z - 1][0] != num_list[z][0]:
break
z = z - 1
if sum >= max: # 等号是因为多个阈值均可以达到最高准确率时,选取其中最大的
max = sum
record = num_list[j][0]
print(record)