zoukankan      html  css  js  c++  java
  • CodeForces

    题目链接:http://codeforces.com/problemset/problem/612/D


    题目大意:

    给出n条线段,让你算这些线段重合次数大于等于k次的部分


    输入: 

    第一行:给出两个数n  k      分别表示要输入的线段个数和所需的线段最少重叠次数

    接下来n行 每行一个l  r表示线段的左端点和右端点。


    解题思路:

    至于这道题:区间覆盖问题 ,先把所有线段进行处理

    对于每条线段e ,对于左端点,将值记下并且标记为0存入结构体数组,右端点将 值 记下标记为1存入结构体数组

    然后让值从小到大对结构体排序,若值相同将0排在前面(过一会你就知道为什么了)


    这样处理后共有2*n个点,定义一个变量cnt记录贡献值

    当遇到标记为1时--cnt表示这次之后这点被覆盖了cnt次

    遇到标记为0时++cnt;  表示这次之后这点被覆盖了cnt次

    当cnt增加到k时就要将这个点作为覆盖k次的左端点,

    当cnt减少到k-1时就要把这个点作为覆盖k次结束的右端点


    前面提到若值相同将则将标记为0的排在前面,是为了下面这样的数据  

    3   2

    0 10

    0 5

    5 10

    因为将左端点排在左边 才能将0 5 ,5 10这样的区间看作一个区间(因为cnt是先加后减的)

    代码:


    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<iostream>
    #include<cstdlib>
    #include<queue>
    #define N 1010000
    #define INF 0x3f3f3f3f
    #define MOD 100007
    using namespace std;
    struct node
    {
        int d,sign;
    } e[2*N];
    bool cmp(node q,node qq)
    {
        if(q.d==qq.d)
            return q.sign<qq.sign;//0   1 ,0在前
        return q.d<qq.d;
    }
    int ll[N];
    int rr[N];
    int main()
    {
        int cnt,n,k,l,r,le,la;
        scanf("%d %d",&n,&k);
        le=0;
        for(int i=1; i<=n; i++)
        {
            scanf("%d %d",&l,&r);
            e[le].d=l;
            e[le++].sign=0;//左端点
            e[le].d=r;
            e[le++].sign=1;//右端点
        }
        sort(e,e+le,cmp);
        la=0;
        cnt=0;//记录在此点以及之前左端点的出现次数
        for(int i=0; i<le; i++)
        {
            if(!e[i].sign)
            {
                cnt++;
                if(cnt==k)
                    ll[la]=e[i].d;
            }
            else
            {
                cnt--;
                if(cnt==(k-1))
                   rr[la++]=e[i].d;
            }
        }
        printf("%d
    ",la);
        for(int i=0;i<la;i++)
            printf("%d %d
    ",ll[i],rr[i]);
    }

  • 相关阅读:
    怎么对Navicat for Oracle 调试
    老版本的java代码与新代码如何找出差异
    Oracle 外部表是做什么用的
    如何在Navicat 中编辑和记录
    如何使用文件对比工具文件夹比较会话菜单
    哪些工具可以用来进行Bug管理
    5类开发者须知的工具
    怎么找出代码之间的差异
    Beyond Compare不仅可以修改网页代码
    文件对比工具有哪些用途
  • 原文地址:https://www.cnblogs.com/dchnzlh/p/9780067.html
Copyright © 2011-2022 走看看