zoukankan      html  css  js  c++  java
  • 【codeforces 496E】Distributing Parts

    【题目链接】:http://codeforces.com/contest/496/problem/E

    【题意】

    给你n个歌曲;
    每个歌曲有一个需要声音的区间li,ri;
    然后给你m个人;
    每个人也有一个声音区间Li,Ri以及最多能唱的歌曲数目ki;
    某个人能唱某首歌当且仅当Li<=li&&ri<=Ri
    问你要如何分配这n首歌给哪些人唱
    或输出无解;

    【题解】

    把和n+m个区间按照左端点排序;
    左端点一样,就把人排在前面;
    然后顺序枚举;
    对于人,直接把它加入到multiset中;
    (这里可以只存右端点,因为左端点没用了);
    然后对于枚举到的歌;
    看看multiset里面有没有人能够唱;
    因为左端点肯定都比这首歌左;
    所以只要看看右端点会不会比它大就好;
    选哪个呢?
    一定是选右端点最小的,但是在这首歌右边的人;
    这样,能最大限度的利用其它人(右端点大的留在后面用,万一能唱右端点更大的歌的呢);
    选定某个人之后,他能唱的歌数递减;
    如果他已经不能唱歌了,就把它从multiset中取出来;
    multiset的重载函数最好这样写,那个friend bool operator 老是出问题

        bool operator < (const node & temp)const{
            return r<temp.r;
        }


    【Number Of WA

    1

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ms(x,y) memset(x,y,sizeof x)
    #define Open() freopen("F:\rush.txt","r",stdin)
    #define Close() ios::sync_with_stdio(0),cin.tie(0)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 2e5+100;
    
    struct abc{
        int l,r;
        int flag,num,id;
    };
    
    struct abc1{
        int l,r,num,id;
        bool operator < (const abc1& tmp)const{
            return r<tmp.r;
        }
    };
    
    int n,m,ans[N],num[N];
    abc a[N];
    multiset <abc1> dic;
    
    void out(){
        cout << "NO" <<endl;
        exit(0);
    }
    
    bool cmp(abc a,abc b){
        if (a.l!=b.l)
            return a.l < b.l;
        else
            return a.flag > b.flag;
    }
    
    int main(){
        //Open();
        Close();
        cin >> n;
        rep1(i,1,n){
            cin >> a[i].l >> a[i].r;
            a[i].flag = 0,a[i].id = i;
        }
        cin >> m;
        rep1(i,n+1,n+m){
            cin >> a[i].l >> a[i].r >> num[i-n];
            a[i].flag = 1,a[i].id = i-n;
        }
        sort(a+1,a+1+n+m,cmp);
        rep1(i,1,n+m){
            abc1 temp;
            temp.l = a[i].l,temp.r = a[i].r,temp.id = a[i].id;
            if (a[i].flag ==0){
                if (dic.empty()) out();
                multiset <abc1>::iterator t = dic.lower_bound(temp);
                if (t == dic.end()) out();
                ans[a[i].id] = t->id;
                num[t->id]--;
                if (!num[t->id]) dic.erase(t);
            }else {
                dic.insert(temp);
            }
        }
        cout <<"YES"<<endl;
        rep1(i,1,n) cout << ans[i] <<' ';
        return 0;
    }
    
  • 相关阅读:
    C# winform窗体间传值(使用委托或事件)
    C# ListView用法详解
    C# ListView列表包含添加和删除,自动排序
    C#跨窗体传值的几种方法分析(很详细)
    c#listview控件的数据添加和常用事件的处理
    C#中结构体与字节流互相转换 [StructLayout(LayoutKind.Sequential)]
    C# winform 操作access常用类
    发行自己的区块链加密货币
    以太坊自助发币
    supervisor常用命令
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626260.html
Copyright © 2011-2022 走看看