codeforces 556D Case of Fugitive

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011528035/article/details/72729462

题意:一条线上有个n个大陆,范围给定且不相交,现在要邻近的大陆搭n-1座桥(桥的两段要在大陆上),给你m座桥的长度,问你怎么分配?


思路:其实就是n-1个区间和m个数,从m个数里面挑n-1个数一一对应区间,这个要求不小于左区间,不大于右区间。


先对区间的左区间排序,从假设从1开始走,如果遇到左区间就塞入区间,如果遇到超出区间范围就剔除(就是没有匹配到,输出no了),但是如果遇到桥长度就剔除右区间最小的(优先队列),这样有利于匹配(贪心),最后输出答案。


数据范围大,先离散化。


#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;

#define LL long long
#define maxn 200005

struct node
{
    LL l;
    LL r;
    int id;

    bool operator <(node a) const  {  return r > a.r; }
};
priority_queue<node> q;

struct edge
{
    LL l;
    int id;
};

node rr[maxn];
edge e[maxn];
int ans[maxn];
LL c[maxn*3];
int cnt;

int cmp1(node a,node b)
{
    return a.l<b.l;
}

int cmp2(edge a,edge b)
{
    return a.l<b.l;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    LL l1,r1,l2,r2;
    scanf("%lld%lld",&l1,&r1);
    for(int i=1;i<n;i++)
    {
        scanf("%lld%lld",&l2,&r2);
        rr[i].id=i;
        rr[i].l=l2-r1;
        rr[i].r=r2-l1;

        l1=l2;
        r1=r2;

        c[++cnt]=rr[i].l;
        c[++cnt]=rr[i].r;
    }
    sort(rr+1,rr+n,cmp1);
    for(int i=1;i<=m;i++)
    {
        scanf("%lld",&e[i].l);
        e[i].id=i;
        c[++cnt]=e[i].l;
    }
    sort(e+1,e+m+1,cmp2);
    sort(c+1,c+cnt+1);

    int x=1,y=1;
    for(int i=1;i<=cnt;i++)
    {
        if(c[i]==c[i-1])continue;
        while(x<=n-1&&rr[x].l==c[i])
            q.push(rr[x++]);
        while(y<=m&&e[y].l==c[i])
        {
            if(!q.empty())
            {
                node f=q.top();
                q.pop();
                ans[f.id]=e[y++].id;
            }
            else
                y++;
        }
        while(!q.empty())
        {
            node f=q.top();
            if(f.r==c[i])
            {
                printf("No\n");
                return 0;
            }
            else
                break;
        }
    }

    printf("Yes\n");
    for(int i=1;i<n;i++)
        printf("%d ",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u011528035/article/details/72729462