题目:CSP2020.12-2
顿顿评估了m位同学上学期的安全指数,其中第i(1≤i≤m)位同学的安全指数为yi,是一个[0,108]范围内的整数;同时,该同学上学期的挂科情况记作resulti∈0,1,其中0表示挂科、1表示未挂科。
相应地,顿顿用predictθ(y)表示根据阈值θ将安全指数y转化为的具体预测结果。
如果predictθ(yj)与resultj相同,则说明阈值为θ时顿顿对第j位同学是否挂科预测正确;不同则说明预测错误。
最后,顿顿设计了如下公式来计算最佳阈值θ∗:
该公式亦可等价地表述为如下规则:
- 最佳阈值仅在yi中选取,即与某位同学的安全指数相同;
- 按照该阈值对这m位同学上学期的挂科情况进行预测,预测正确的次数最多(即准确率最高);
- 多个阈值均可以达到最高准确率时,选取其中最大的
算法思想: 构建结构体对输入的yj与resultj进行存储,再根据yj利用sort函数对结构体数组进行从小到大的排序,构建一个前缀和数组front_sum来存储L[0].R到L[i].R的总和并计算所有L[i].R的总和sum,i - front_sum[i-1] + 1是L[i]前为0的个数,sum - front_sum[i-1]是L[i]后(包括L[i])为1的个数。二者相加为正确预测的个数,在统计预测正确个数的时候,若存在L[i]的y值相同的情况,需要将其跳过。
运行结果:csp官网验证结果:100分。
#include <iostream> #include<algorithm> using namespace std; struct Y_R { int y; int R; }L[100000]; int front_sum[100000], correct_predict[100000]; bool cmp(Y_R a, Y_R b) { if (a.y != b.y) { return a.y <= b.y; } return a.R <= b.R; } int main() { int m, sum, max_y = 0, max_predict = 0; cin >> m; for (int i = 0; i < m; i++) { cin >> L[i].y >> L[i].R; } sort(L, L + m, cmp);//将输入的从小到大排序 front_sum[0] = L[0].R; sum = L[0].R; for (int i = 1; i < m; i++) { front_sum[i] = front_sum[i - 1] + L[i].R; sum += L[i].R; } correct_predict[0] = sum; max_predict = correct_predict[0]; max_y = L[0].y; for (int i = 1; i < m; i++) { if (L[i].y == L[i - 1].y) { continue; } correct_predict[i] = i - front_sum[i-1] + 1 + sum - front_sum[i-1];//i - front_sum[i-1] + 1是L[i]前为0的个数,sum - front_sum[i-1]是L[i]后(包括L[i])为1的个数。 if (max_predict <= correct_predict[i]) { max_predict = correct_predict[i]; max_y = L[i].y; } } cout << max_y; return 0; }