Educational Codeforces Round 4 D. The Union of k-Segments(★)

题意:

给定n个区间,问你被覆盖至少k次的区间最少有多少个,并输出.

思路十分简洁,一个区间若被覆盖k次,则在这个区间前至少要出现k个线段的起点,且出现的起点减去终点数量不能小于k,这样排下序,线段起点+1,终点-1,判断下是否大于k一遍遍历下来就出答案了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF  0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-3
#define maxn 2000010
#define MOD 100000007
struct node
{
    int val,flag;
    bool operator <(const node &a)const
    {
        return val < a.val || (val == a.val && flag < a.flag);
    }
}a[maxn];
int n,k,ans[maxn];

int main()
{
    int t,c = 1;
    //scanf("%d",&t);
    while(scanf("%d%d",&n,&k) != EOF)
    {
        for(int i = 0; i < n; i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            a[2*i].val = x;
            a[2*i].flag = 0;
            a[2*i+1].val = y;
            a[2*i+1].flag = 1;
        }
        sort(a,a+2*n);
        int cnt = 0,num = 0;
        for(int i = 0; i < 2*n; i++)
        {
            if(a[i].flag == 0)
            {
                cnt++;
                if(cnt == k)
                    ans[num++] = a[i].val;
            }
            else
            {
                if(cnt == k)
                    ans[num++] = a[i].val;
                cnt--;
            }
        }
        printf("%d\n",num/2);
        for(int i = 0; i < num; i+= 2)
            printf("%d %d\n",ans[i],ans[i+1]);
    }
    return 0;
}


你可能感兴趣的:(思维)