CSP 202012-2 前后缀

2 期末预测之最佳阈值

题意

y < θ , p r e d i c t ( y ) = 0 y< \theta,predict(y)=0 y<θpredict(y)=0
y > = θ , p r e d i c t ( y ) = 1 y>= \theta,predict(y)=1 y>=θpredict(y)=1
在这里插入图片描述

样例说明

在这里插入图片描述

# Input
6
0 0
1 0
1 1
3 1
5 1
7 1
# Output
3

Round 1

在这里插入图片描述
果然 直接暴力去处理的话 只能过70%样例的,70分无疑了hhh
这里得优化一下呀 (上来先一发暴力试试水~ 其实这里应该可以再先 从大到小 排个序,因为它本来最后的结果那里会要取最大,所以我们最开始其实可以从大的来算 或许也能优化一点点~)

//#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <set>
using namespace std;
const int mod=1e9+7;
const int maxn=1e5+5;
int a[maxn][5];
set<int> h;//用一个set去装可能的阈值,然后在从中去找到
int main()
{
    int m;
    cin>>m;
    for(int i=0;i<m;i++)
    {
        cin>>a[i][0]>>a[i][1];
        h.insert(a[i][0]);
    }    
    set<int>::iterator t;
    int highest,maxt;
    highest=0,maxt=0;
    
    for(t=h.begin();t!=h.end();t++)
    {
        int cnt=0;
        for(int i=0;i<m;i++)
        {
            if(a[i][0]<(*t)&&a[i][1]==0)
                cnt++;
            else if(a[i][0]>=(*t)&&a[i][1]==1)
                cnt++;
        }
        //cout<<"---"<<endl;
        //cout<<(*t)<<" "<<cnt<<endl;
        if(cnt>=highest)
        {
            highest=cnt;
            maxt=max(maxt,(*t));
            //cout<<"h "<<highest<<" t "<<maxt<<endl;
        }    
    }

    cout<<maxt<<endl;
    return 0;
}

Round 2

我们通过观察可以知道,它必然有一部分前后是重叠的,会有 重复计算 ,所以我们就应该想想怎么去除掉这些重复计算。

比如计算7的情况的时候,必然会用到5的情况,计算阈值为7情况下的个数统计必然包括要阈值为5时的个数统计,所以我们其实可以先 前后向 预处理出所有结果的,然后直接遍历输出结果就好啦,其实很简单啊。

(这里突然想到,排序是确实得排一排的,因为这里相当于有一个迭代的过程嘛,但其实哪一种方式排其实都是OK的,或者说,从小到大排前期会更方便点,如上的举例可以看到。既然要排序,那咱们就struct node嘛~)

//#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;
const int mod=1e9+7;
const int maxn=1e5+5;
struct node{
    int y;
    int res;
    int cnt;
}a[maxn];

bool cmp(node a,node b)
{
    if(a.y==b.y)
        return a.res<b.res;

    return a.y<b.y;
}
int main()
{
    int m;
    cin>>m;
    for(int i=0;i<m;i++)
    {
        cin>>a[i].y>>a[i].res;
        a[i].cnt=0;
    }
    sort(a,a+m,cmp);

    // 前向记录 res=0是预测对的
    int cnt0=0;//从这里开始,一切以计算前向0个数为基准进行
    if(a[0].res==0)//初始化 第一个是0,则计数+1
        cnt0++;
    for(int i=0;i<m;i++)
    { 
        //cout<<i<<" "<<cnt0<<endl;
        if(a[i].y>a[i-1].y)
            a[i].cnt=cnt0;//更新 到目前为止的0的个数 
        else if(a[i].y==a[i-1].y)
            a[i].cnt=a[i-1].cnt;//保持   
        if(a[i].res==0)// 0的计数应该放在最后是因为 上面累加的需要是前一次更新的cnt0
            cnt0++;    
    }
    // 后向记录 res=1是预测对的
    int cnt1=0,max=-1,ans=0;
    for(int i=m-1;i>=0;i--)
    {
        if(a[i].res==1)// theta=y[i] 的时候,这准确的预测值必是1
            cnt1++;
        a[i].cnt+=cnt1;//加上包括自己的
        if(a[i].cnt>max)
        {
            max=a[i].cnt;
            ans=a[i].y;
        }          
    }
    cout<<ans<<endl;
    return 0;
}

还有一点需要注意的是: 这里用直接用sort() 一定要加头文件 #include <algorithm>,不然会 编译错误 。或者干脆直接套万能头吧,但是练习的时候不建议哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值