1 条题解

  • 1
    @ 2019-01-20 09:17:51

    本题两种做法均可AC。
    一、定义四个变量,O(n)时间

    #include<iostream>
    using namespace std;
    int group[1000000];
    int main()
    {
        int gnum,top,bottom;
        cin>>gnum;
        for(int i=0;i<gnum;i++)
        {
            cin>>group[i];
        }
        cin>>bottom>>top;
        long long moretop=0,morebottom=0,lesstop=0,lessbottom=0;
    /*
    moretop 所有组中大于上界的人数和
    morebottom 所有组中大于下界的人数和
    lesstop  所有组中小于上界的人数和
    lessbottom 所有组中小于下界的人数和 
    */ 
        for(int i=0;i<gnum;i++)
        {
            if(group[i]<bottom)
            {
                lesstop+=(long long)top-group[i];
                lessbottom+=(long long)bottom-group[i];
            }
            else if(group[i]<top)
            {
                lesstop+=(long long)top-group[i];
                morebottom+=(long long)group[i]-bottom;
            }
            else
            {
                moretop+=(long long)group[i]-top;
                morebottom+=(long long)group[i]-bottom;
            }
        }
    //极端情况是每组学生数都是上界或都是下界
    //moretop>lesstop 过上界的学生数大于小于上界的学生数,也就是总学生数过多,不可以
    //morebottom<lessbottom 同上理,总学生数太少,不可以 
        if(moretop>lesstop||morebottom<lessbottom)
        {
            cout<<-1<<endl;
        }
    //最少调整应取max,因为既要>=下界,又要<=上界 
        else
        {
            cout<<max(lessbottom,moretop)<<endl;
        }
        return 0; 
    }
    

    二、模拟,时间复杂度略大,约为O(nlogn)

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int group[1000000];
    int main()
    {
        int gnum;
        cin>>gnum;
    
        int top,bottom; 
        for(int i=0;i<gnum;i++)
            cin>>group[i];
        sort(group,group+gnum);
        cin>>bottom>>top;
        int curl=0,curr=gnum-1;
        long long ans=0;
        //首先将大于上界或小于下界的学生互补 
        while(curl<curr)
        {
            if(group[curl]>=bottom||group[curr]<=top)   break;
            if(group[curr]-top>bottom-group[curl])
            {
                ans+=(long long)bottom-group[curl];
                group[curr]-=bottom-group[curl];
                group[curl]=bottom;
                curl++;
            }
            else
            {
                ans+=(long long)group[curr]-top;
                group[curl]+=group[curr]-top;
                group[curr]=top;
                curr--;
            }
        }
        sort(group,group+gnum);
    //若仍然有小于下界的学生,那么此时所有组均<=上界,再用大于下界的填小于下界的 
        if(group[0]<bottom)
        {
            curl=0;curr=gnum-1;
            while(curl<curr)
            {
                if(group[curl]>bottom||group[curr]<bottom)  break;
                if(group[curr]-bottom>bottom-group[curl])
                {
                    ans+=(long long)bottom-group[curl];
                    group[curr]-=bottom-group[curl];
                    group[curl]=bottom;
                    curl++;
                }
                else
                {
                    ans+=(long long)group[curr]-bottom;
                    group[curl]+=group[curr]-bottom;
                    group[curr]=bottom;
                    curr--;
                }
            }
            for(int i=0;i<gnum;i++)
            {
                if(group[i]<bottom||group[i]>top)
                {
                    ans=-1;
                    break;
                }
            }
        }
    //若仍然有大于上界的学生,那么此时所有组均>=下界,再用大于上界界的填小于上界界的  
        else
        {
            curl=0,curr=gnum-1;
            while(curl<curr)
            {
                if(group[curl]>top||group[curr]<=top)   break;
                if(group[curr]-top>top-group[curl])
                {
                    ans+=(long long)top-group[curl];
                    group[curr]-=top-group[curl];
                    group[curl]=top;
                    curl++;
                }
                else
                {
                    ans+=(long long)group[curr]-top;
                    group[curl]+=group[curr]-top;
                    group[curr]=top;
                    curr--;
                }
            }
            for(int i=0;i<gnum;i++)
            {
                if(group[i]<bottom||group[i]>top)
                {
                    ans=-1;
                    break;
                }
            }
        }
        cout<<ans<<endl;
        return 0;
    } 
    
  • 1

信息

难度
7
分类
(无)
标签
(无)
递交数
155
已通过
26
通过率
17%
被复制
3
上传者