202012-2期末预测之最佳阈值

题目背景

考虑到安全指数是一个较大范围内的整数、小菜很可能搞不清楚自己是否真的安全,顿顿决定设置一个阈值,以便将安全指数转化为一个具体的预测结果——“会挂科”或“不会挂科”。因为安全指数越高表明小菜同学挂科的可能性越低,所以当时,顿顿会预测小菜这学期很安全、不会挂科;反之若,顿顿就会劝诫小菜:“你期末要挂科了,勿谓言之不预也。”那么这个阈值该如何设定呢?顿顿准备从过往中寻找答案。

题目描述

具体来说,顿顿评估了n位同学上学期的安全指数,其中第 i 位同学的安全指数为 yi,是一个[0,1e8] 范围内的整数;同时,该同学上学期的挂科情况记作result ,其中 0 表示挂科,1 表示未挂科。等价地表述为如下规则:

1.最佳阈值仅在yi中选取,即与某位同学的安全指数相同;

2.按照该阈值对这m位同学上学期的挂科情况进行预测,预测正确的次数最多(即准确率最高);

3.多个阈值均可以达到最高准确率时,选取其中最大的。

输入格式

从标准输入读入数据。输入的第一行包含一个正整数m。接下来输入m行,其中第i行包括用空格分隔的两个整数 yi 和 result,含义如上文所述。

输出格式

输出到标准输出。输出一个整数,表示最佳阈值。

分析: 

首先把题目数据按照从小到大排好序,根据题意可以看出来,预测正确的次数也就是每一个yi左边的0的个数加上自身以及自身右边1的个数的总和sum,要求最终就是求最大sum所对应的最大yi。但是有一点需要注意的是:当出现重复的yi的时候只记录第一次的数据,因为只有它第一次出现的时候,它前面的0才是它预测正确的0,它后面的1是它预测正确的1,也就是类似于赋值一样,对于下图中的第二个1而言,其前已经出现的yi = 1,result = 0相当于是既定事实了,后面出现的 1,1就和前面相违背为了,因此不计算重复的yi对应的sum值。

202012-2期末预测之最佳阈值_第1张图片

代码如下:

#include 
#include 
using namespace std;
const int N = 100010;
typedef pair PII;
PII all[N];
int sum0[N],sum1[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++)
        scanf("%d%d",&all[i].first,&all[i].second);
    sort(all+1,all+n+1);
    for(int i = 1;i <= n;i++)
    {
        sum0[i] = sum0[i-1];
        sum1[i] = sum1[i-1];
        if(!all[i].second)
            sum0[i] += 1;
        else
            sum1[i] += 1;
    }
    int ans = 0;
    int max_yi;
    for(int i = 1;i <= n;i++)
    {
        if(all[i].first == all[i-1].first)
            continue;
        int t = sum0[i-1]+sum1[n]-sum1[i-1];
        if(t >= ans)
        {
            ans = t;
            max_yi = all[i].first;
        }
    }
    printf("%d",max_yi);
    return 0;
}

 

你可能感兴趣的:(算法)