CSP202012-2 期末預測之最佳閾值
阿新 • • 發佈:2021-01-27
CSP202012-2 期末預測之最佳閾值
題目
題目可以在CSP的官網檢視到喲!
演算法思想
這道題要做的就是尋找最佳的閾值,使得預測正確的數量最多。看過最後的資料範圍,發現2<=m<=100000,這道題很容易想到O(n * n)的演算法,但是肯定會超時,因此需要一個時間複雜度較低的演算法。接下來,小編介紹的演算法時間複雜度是O(n*logn)。
首先對閾值進行排序,按照閾值從大到小進行排序,可以很容易地想到,在選擇的閾值之前的預測為0的是預測正確的,在閾值之後的預測為1的是預測正確的,因此提前生成兩個陣列,一個數組記錄該點 之前預測為0的數量,另一個數組記錄該點之後(包括該點)預測為1的數量,而對於該點,兩個陣列相加就是以該點數值為閾值的預測正確的數量。
排序之後,利用字首和和字尾和的思想,分別統計某一點之前預測為0的數量以及某一點之後(包括該點)預測為1的數量,之後尋找兩者相加最大值所對應的最大閾值即可。
完整程式碼
#include<iostream>
#include<cstdio>
#include<algorithm>
#pragma warning (disable:4996)
using namespace std;
int m;
struct Person
{
int y, result;
}person[200000];
int sum0[200000], sum1[200000];
bool cmp(Person a, Person b)
{
if (a.y != b.y) return a.y < b.y;
else return a.result > b.result;
}
int main()
{
freopen("in.in", "r", stdin);
freopen ("out.out", "w", stdout);
int i, j;
cin >> m;
for (i = 1; i <= m; i++)
cin >> person[i].y >> person[i].result;
sort(person + 1, person + m + 1, cmp);
sum0[0] = 0;
sum0[1] = 0;
for (i = 2; i <= m; i++)
{
if (person[i - 1].result == 0)
sum0[i] = sum0[i - 1] + 1;
else sum0[i] = sum0[i - 1];
}
sum1[m + 1] = 0;
for (i = m; i >= 1; i--)
{
if (person[i].result == 1)
sum1[i] = sum1[i + 1] + 1;
else sum1[i] = sum1[i + 1];
}
int max_y = 0, max_num = 0;
for (i = 1; i <= m; i++)
{
int num = sum0[i] + sum1[i];
if (num >= max_num)
{
max_y = person[i].y;
max_num = num;
}
}
cout << max_y << endl;
return 0;
}