• 559 div2 The Party and Sweets*


      题意:给出n个数代表男生 m个数代表女生

    要求每个男生给所有女生几个糖果(可以是0个)

    每个男生给各个女生糖果的最小值(不是总和) 大于等于男生代表的值

    给每个女生的糖果小于等于女生的值  且每个女生至少收到一份足够多的糖果(代表她的值的糖果数量)

    ps:男生给各个女生的糖果数量也至少有一个==其男生值

    贪心:

    显然 男生值小的给女生值大的 是比较亏的  损失值为差值    所以要安排男生值大的给女生值大的  按照男生值大的遍历下来即可  要注意得留一个补自己的值

    比赛的时候几乎写出来了  但是数组没有开longlong   

    数据范围为1e8  但是乘的过程中爆int了  

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=400000+5;
    ll a[N],b[N];
    int main()
    {
        int n,m;RII(n,m);
        rep(i,1,n)scanf("%lld",&a[i]);
        rep(i,1,m)scanf("%lld",&b[i]);
        sort(a+1,a+1+n);
        sort(b+1,b+1+m);
    
        if(a[n]>b[1])
        printf("-1");
        else
        {
            ll sum=0;
            int R=m;
            repp(i,n,1)
            {
                if(R==0)
                {
                    sum+=a[i]*m;continue;
                }
                int t=m-1;
                while(t&&R>=1)
                {
                    sum+=b[R];
                    R--;t--;
                }
                if(t==0)
                {
                    sum+=a[i];
                    if(a[i]==b[R])R--;
                    continue;
                }
                else if(t)
                {
                    t++;
                    while(t--)
                    sum+=a[i];
                }
            }
            cout<<sum;
        }
        return 0;
    }
    108ms

    其实仔细观察发现  从男生最大值开始遍历  要么一遍遍历结束(如果男生最大值==女生最小值) 要么男生遍历m-1个  剩下一个最小的男士次小值遍历即可!!!

     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); 用了这个 在下面用scanf就wa了!!!!!  我还是老老实实用scanf好了

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    const int N=400000+5;
    ll maxx=0,maxx2=0,minn=(int)1e9;
    ll sumboy=0,sumgirl=0; ll x;ll ans=0;
    int n,m;
    int main()
    {   
        RII(n,m);
        rep(i,1,n)
        {
            scanf("%lld",&x);
            if(x>=maxx)
            {
                maxx2=maxx;
                maxx=x;
            }
            else if(x>maxx2)
                maxx2=x;
            sumboy+=x;
        }
        rep(i,1,m)
        {
            scanf("%lld",&x);
            if(x<minn)minn=x;
            sumgirl+=x;
        }
        if(maxx>minn)
        {
            printf("-1");return 0;
        }
        
        ans = sumboy*(ll)m;
        ans += sumgirl;
        ans -= maxx*m;
        if(maxx!=minn)
        ans += maxx-maxx2;
        cout << ans;
    
        return 0;
    }
    View Code

    注意维护第二大数的方法值得学习

  • 相关阅读:
    GoGin 跨域处理
    Vue sso认证快速接入实践
    领域驱动设计(DDD):项目目录(包、模块)结构
    高绩效团队建设与管理系列课程
    VR设备产业链
    Supercell资深策划谈三大产品制作经验:游戏设计就像丛林探险,必须险中求胜
    领导力管理培训课
    博众投资:虚拟数字人概念,开辟元宇宙炒作新战场!
    FW: Flow区块链门票NFT开发实战【含源码】
    放弃学术研究,做投资大获成功
  • 原文地址:https://www.cnblogs.com/bxd123/p/10859800.html
Copyright © 2020-2023  润新知