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

题面

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

样例

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

// input
6
0 0
1 0
1 1
3 1
5 1
7 1
//output
3

// input
8
5 1
5 0
5 0
2 1
3 0
4 0
100000000 1
1 0
//output
100000000

Round 1   90分

差不多像是前缀和问题,CSP的第二道大多数都是这个思路。

整体问题求解分成三个部分:遍历到第i个阈值为m,正确的数量 cnt=zeros[0:i)+ones(i:n-1]+is_one(i),后续需要处理一下重复部分。

写完才发现… 忽略了另外一个样例的情况… 【具有同值重复0和同值重复1的情况】(纯粹是没认真读题读样例了… 但感觉这个思路还是OK的…)

#include 
#include 
#include 
using namespace std;
const int maxn=1e5+5;
struct node{
    int y,res,cnt=0;
}a[maxn];
int num[2][maxn];// 记录前i个
bool cmp(node p,node q)
{
    if(p.y==q.y)
        return p.res<q.res;
    return p.y<q.y;
}
int main()
{
    int n;
    cin>>n;
    memset(num,0,sizeof(num));
    for(int i=0;i<n;i++)
    {
        cin>>a[i].y>>a[i].res;
    }
    sort(a,a+n,cmp);
    // for(int i=0;i
    //     cout<
    num[0][0]=0;
    for(int i=1;i<n;i++)
    {
        if(a[i-1].res==0)
            num[0][i]=num[0][i-1]+1;
        else
            num[0][i]=num[0][i-1];
    }
    num[1][n-1]=0;
    for(int i=n-2;i>=0;i--) // 记录后i个为1的个数(不包括自己)
    {
        if(a[i+1].res==1)
            num[1][i]=num[1][i+1]+1;
        else
            num[1][i]=num[1][i+1];
    }
    // for(int i=0;i<2;i++)
    // {
    //     for(int j=0;j
    //         cout<
    //     cout<
    // }   
    
    for(int i=0;i<n;i++)
    {
        if(a[i].y==a[i+1].y)
        {   
            a[i+1].cnt-=1;//只处理了存在同值res=0/1的情况,见样例1
            i+=1;
            //cout<
        }
        if(a[i].res==1)
            a[i].cnt+=num[0][i]+num[1][i]+1;
        else
            a[i].cnt+=num[0][i]+num[1][i];
        //cout<
    }
    int maxcnt=a[0].cnt;
    int idx=0;
    for(int i=1;i<n;i++)
    {
        //cout<
        if(a[i].cnt>maxcnt)
        {
            maxcnt=a[i].cnt;
            idx=a[i].y;
        }
        else if(a[i].cnt==maxcnt&&a[i].y>idx)
            idx=a[i].y;
    }
    cout<<idx<<endl;
    return 0;
}

简单的对输入去重是不可行的。

AC 100分

注意要去重,阈值遍历到该值时,如果res为1,则是应记录的。如果该值左边有重复0,应该减去相应的个数;如果res为0,右边重复1的情况同理。

#include 
#include 
#include 
using namespace std;
const int maxn=1e5+5;
struct node{
    int y,res,cnt=0;
}a[maxn];
int num[2][maxn];// 记录第i个数前面0的个数和后面1的个数
bool cmp(node p,node q)
{
    if(p.y==q.y)
        return p.res<q.res;
    return p.y<q.y;
}
int main()
{
    int n;
    cin>>n;
    memset(num,0,sizeof(num));
    for(int i=0;i<n;i++)
    {
        cin>>a[i].y>>a[i].res;
    }
    sort(a,a+n,cmp);
    // for(int i=0;i
    //     cout<
    //开始记录前面0和后面1的个数
    num[0][0]=0;
    for(int i=1;i<n;i++)
    {
        if(a[i-1].res==0)
            num[0][i]=num[0][i-1]+1;
        else
            num[0][i]=num[0][i-1];
    }
    num[1][n-1]=0;
    for(int i=n-2;i>=0;i--) // 记录后i个为1的个数(不包括自己)
    {
        if(a[i+1].res==1)
            num[1][i]=num[1][i+1]+1;
        else
            num[1][i]=num[1][i+1];
    }
    // for(int i=0;i<2;i++)
    // {
    //     for(int j=0;j
    //         cout<
    //     cout<
    // }   
    
    for(int i=0;i<n;i++)
    {
        //这种写法只考虑到了左边同值重复0的情况,没有考虑到右边重复1的情况
        // if(a[i].y==a[i+1].y&&a[i].res==a[i+1].res)
        // {   
        //     if(a[i].res==0)
        //         a[i+1].cnt-=1;
        //     i+=1;
        //     //cout<
        // }
        // a[i+repeat].cnt-=repeat;
        
        if(a[i].res==1)
        {
            a[i].cnt+=num[0][i]+num[1][i]+1;
            int repeat=0;//同值情况 左边多出来0的个数
            for(int k=i;k>=0;k--)
            {
                if(a[k].res==0)
                    repeat++;
                if(a[k].y!=a[k-1].y)
                    break;
            }
            //cout<
            a[i].cnt-=repeat;
        }
        else
        {
            a[i].cnt+=num[0][i]+num[1][i];
            int repeat=0;//同值情况 右边多出来1的个数
            for(int k=i;k<n;k++)
            {
                if(a[k].res==1)
                    repeat++;
                if(a[k].y!=a[k+1].y)
                    break;
            }
            //cout<
            a[i].cnt-=repeat;
        }
    }
    // for(int i =0;i
    //     cout<
    //     cout<<"****"<
    
    int maxcnt=a[0].cnt;
    int idx=0;
    for(int i=1;i<n;i++)
    {
        //cout<
        if(a[i].cnt>maxcnt)
        {
            maxcnt=a[i].cnt;
            idx=a[i].y;
        }
        else if(a[i].cnt==maxcnt&&a[i].y>idx)
            idx=a[i].y;
    }
    cout<<idx<<endl;
    return 0;
}

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