zoukankan      html  css  js  c++  java
  • [EOJ]2019 ECNU XCPC March Selection #1 F

    题意:数轴上有n个点,m条线段,选出尽量多的线段,使每条线段都能独立地占有至少一个点(不可公用同一个点)。

    线段覆盖问题,按右端点升序,右端点相同时左端点降序排序,画图可以看出前边的线段应该尽量用前边的点,把点排序,依此对每条线段二分查找可以用的点。

    (考场上开始没想清楚,用左端点做了第一关键字,后来好好画图很容易看出来应该用右端点做第一关键字)

    比较典型的一道题。

    #include<bits/stdc++.h>
    using namespace std;
    
    
    typedef long long LL ;
    
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define pb push_back
    #define st first
    #define nd second
    #define mp make_pair
    #define pii pair<int ,int >
    
    const int N = 2e4+7;
    const int MX = 1e9+7;
    
    int t[N],n,m,tag[N];
    
    pii a[N];
    
    int cmp(pii a,pii b){
        if(a.nd!=b.nd)return a.nd<b.nd;
        return a.st>b.st;
    }
    
    int find(int x){
        int l=1,r=n,ans=n+1;
        while(l<=r){
            int mid=(l+r)/2;
            if(t[mid]>=x){
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        return ans;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        rep(i,n)scanf("%d",&t[i]);
        rep(i,m)scanf("%d%d",&a[i].st,&a[i].nd);
        sort(t+1,t+1+n);
        sort(a+1,a+1+m,cmp);
        int ans=0;
        rep(i,m){
            int x=find(a[i].st);
            while(tag[x]&&x<=n)x++;
            if(x==n+1)continue;
            if(a[i].nd>=t[x]){
                ans++;
                tag[x]=1;
            }
        }
        cout<<ans;
    } 
  • 相关阅读:
    HDU 1333 基础数论 暴力
    HDU 1299 基础数论 分解
    HDU 1211 EXGCD
    HDU 3507 单调队列 斜率优化
    博弈
    std:ios::sync_with_stdio(false);
    NBUT[1220] SPY
    nbut1217 Dinner
    poj2236Wireless Network
    ZOJ Problem Set
  • 原文地址:https://www.cnblogs.com/xutianshu/p/10459497.html
Copyright © 2011-2022 走看看