CCF CSP 202012-2 期末予測ベスト閾値(C++言語で100点)

1. 質問へのリンク: CCF 202012-2 期末予測最適しきい値

質問番号: 202012-2
質問名: 期末予測の最適閾値
制限時間: 1.0秒
メモリ制限: 512.0MB
問題の説明:

トピックの背景

安全指数が比較的大きな範囲内の整数であることを考慮すると、Xiaocai は自分が本当に安全であるかどうか確信が持てない可能性があるため、Dunton は安全指数 y を特定の予測結果に変換するためにしきい値 θ を設定することにしました - 「ハングします。セクション」または「失敗しない」。

安全指数が高いほど、Xiaocai が失敗する可能性が低くなるため、y≧θ の場合、Dundun は Xiaocai が安全であり、今学期に失敗しないと予測します。そうでない場合、y<θ の場合、Dundun は Xiaocai に次のようにアドバイスします。学期の終わりには失敗するだろうから、予測していなかったとは言わないでください。」

では、このしきい値はどのように設定すればよいでしょうか。Dun Dun は、過去から答えを見つける準備ができています。

トピックの説明

具体的には、Dundon は前学期の m 人の生徒の安全指数を評価し、i (1≤i≤m) 人の生徒の安全指数は [0,108] の範囲の整数である yi であると同時に、学期の不合格は結果 ∈ 0,1 として記録されます。ここで、0 は不合格を意味し、1 は不合格ではないことを意味します。

これに対応して、Dundu は predictθ(y) を使用して、しきい値 θ に従って安全指数 y を変換した特定の予測結果を表します。
predictθ(yj) が resultj と同じ場合は、しきい値が θ のときに j 番目の生徒が不合格になるかどうかを Dundun が正しく予測したことを意味し、異なる場合は予測が間違っていたことを意味します。

予測θ(y)={0(y<θ)1(y≥θ)

最後に、Dundon は次の式を設計して、最適なしきい値 θ を計算しました。

θ =maxargmaxθ∈yi⁡∑j=1m(予測θ(yj)==結果j)

この式は、次の規則として同等に表現することもできます。

  1. 最適なしきい値は、同級生の安全指数と同じ yi でのみ選択されます。

  2. しきい値に従って、前学期の m 人の学生の失敗を予測し、正しい予測の数が最も多くなります (つまり、最も高い正解率)。

  3. 複数のしきい値で最高の精度を達成できる場合は、最大のしきい値が選択されます。

入力フォーマット

標準入力からデータを読み取ります。

入力の最初の行には、正の整数 m が含まれています。

次に、m 行を入力します。ここで、i (1≤i≤m) 行には、スペースで区切られた 2 つの整数 yi と resulti が含まれます。意味は上記のとおりです。

出力フォーマット

標準出力に出力します。

最適なしきい値 θ ∗を表す整数を出力します

サンプル1入力

6
0 0
1 0
1 1
3 1
5 1
7 1

サンプル 1 出力

3

例 1 説明

ルール 1 によると、最適なしきい値の選択範囲は 0、1、3、5、7 です。

θ=0 の場合、正しい予測の数は 4 です。

θ=1 の場合、正しい予測の数は 5 です。

θ=3 の場合、正しい予測の数は 5 です。

θ=5 の場合、正しい予測の数は 4 です。

θ=7 の場合、正解数は 3 です。

閾値として 1 または 3 が選択された場合、予測精度が最も高くなるため、
2 番目の規則に従って、最適な閾値の選択範囲は 1、3 に縮小されます。

3 番目の規則によれば、θ =max1,3=3 です。

サンプル 2 入力

8
5 1
5 0
5 0
2 1
3 0
4 0
100000000 1
1 0

サンプル 2 出力

100000000

サブタスク

テスト データの 70% が m≤200 を保証します。

すべてのテスト データは 2≤m≤10 5を保証します。

2. 問題分析:

問題分析を読んだ後、この問題の難しさはmmにありますm人の生徒yyy は繰り返される可能性があり、単純に構造体配列を使用してデータを表すことはできません。最初に、 iiのハッシュ テーブルを使用する必要があります。行iの生徒のyi y_iyそして前学期の失敗resulti result_iresulti进行统计得出考虑重复安全指数的挂科情况,然后转存入一个vector动态数组进行从小到大排序,从小到大遍历递推得出阈值 θ ⩾ \theta \geqslant θ当前安全指数 y i y_i yi时左侧预测正确的次数,即挂科情况为0的数量,最后从大到小遍历边递推得到阈值 θ ⩾ \theta \geqslant θ当前安全指数 y i y_i yi时右侧预测正确的次数,即挂科情况为1的数量,边迭代得出最佳阈值 θ ∗ \theta^* θ。其中,由于迭代是从大到小进行,所以该方法直接满足多个阈值均可以达到最高准确率时,选取其中最大的规则。

3. C++代码程序实现:

#include <bits/stdc++.h>

using namespace std;
struct safetyIndex
{
    
    
    int y,ones_result,zeros_result,zeros_left,ones_right;
    safetyIndex()
    {
    
    
        zeros_result=0;
        ones_result=0;
    }
    bool operator<(const safetyIndex& si)
    {
    
    
        return this->y<si.y;
    }
};
int main()
{
    
    
    int m,yi,result_i,zeros=0,ones=0,pred_true=-1,ans,theta;
    scanf("%d",&m);
    unordered_map<int,safetyIndex> y2result;
    for (int i=0;i<m ;++i )
    {
    
    
        scanf("%d%d",&yi,&result_i);
        y2result[yi].y=yi;
        if (result_i==0)
        {
    
    
            ++y2result[yi].zeros_result;
        }
        else
        {
    
    
            ++y2result[yi].ones_result;
        }
    }
    vector<safetyIndex> si;
    for (auto ele:y2result)
    {
    
    
        si.push_back(ele.second);
    }
    sort(si.begin(),si.end());
    si[0].zeros_left=0;
    for (int i=1;i<si.size();++i )
    {
    
    
        zeros+=si[i-1].zeros_result;
        si[i].zeros_left=zeros;
    }
    for (int i=si.size()-1; i>=0;--i )
    {
    
    
        ones+=si[i].ones_result;
        ans=si[i].zeros_left+ones;
        if (ans>pred_true)
        {
    
    
            pred_true=ans;
            theta=si[i].y;
        }
    }
    printf("%d",theta);
    return 0;
}

4. 提交AC结果:

在这里插入图片描述

おすすめ

転載: blog.csdn.net/m0_46223009/article/details/125198864