题目链接:202012-2期末预测之最佳阈值
思路:
1、用结构体存储数据对,并自己定义cmp方便调用sort对结构体进行排序。
2、定义一个a1和一个a2数组,a1用来存小于当前项0的个数,a2用来存大于等于当前项1的个数
3、最核心的部分,求小于当前项0的个数和大于当前项1的个数,举个例子,下图是给的测试用例排序之后,对应的a1数组和a2数组:大于当前项1的个数很简单,只要从m-1到0倒序计算,当前项出现1时,则cnt1++,然后赋值即可。
小于当前项的0的个数比较麻烦需要考虑如下的情况:
(1) 等于当前项的0是不能计算的,比如说5 0,5 0,cnt0的值不变,所以在if判断条件里面我加上了不不等于前一项的预测值n[i].y!=n[i-1].y,当预测值改变的时候才要计算cnt0的变化
(2)当有重复项的时候,cnt0的变化可能不止1,比如说有两个5 0,导致到下一个预测值时,cnt0直接加了2,这里我选择用vector数组,每次有一个0的时候就就push_back()一次,然后当预测值改变的时候,cnt0加上vector的size再把vector清零。
TIPS:如果不想数组访问越界,以后定义大的数组都定义1ek+2,k=5,6,7...等等,然后开数组从1~n项这样定义在全局变量里面,当出现和前一项后者后一项的比较时不会越界,因为全局变量会自动赋初值为0。
#include <bits/stdc++.h>
using namespace std;
const int maxm=1e5+2;
struct node{
int y;
int r;
}n[maxm];
int a1[maxm],a2[maxm];
bool cmp(node n1,node n2){
if(n1.y==n2.y) return n1.r<=n2.r;
else return n1.y<n2.y;
}
int main(){
int m;
cin>>m;
for(int i=1;i<=m;i++){
cin>>n[i].y>>n[i].r;
}
sort(n+1,n+m+1,cmp);
int cnt0=0,cnt1=0;//cnt0记录小于当前y的项,r=0的个数;cnt1记录大于等于当前y的项,r=1的个数
vector<int> v0;
for(int i=1;i<=m;i++){
if(n[m-i+1].r==1) cnt1++;
a2[m-i+1]=cnt1;
if(n[i].y!=n[i-1].y&&!v0.empty()){
cnt0+=v0.size();
v0.clear();
}
a1[i]=cnt0;
if(n[i].r==0) v0.push_back(0);
}
int max=0,res=0;
for(int i=m;i>=1;i--){
int temp=a1[i]+a2[i];
if(temp>max) {
max=temp;
res=n[i].y;
}
}
cout<<res;
return 0;
}