区间重合判断[poj2808 校门外的树]

题目:http://bailian.openjudge.cn/practice/2808/

参考了文章,重写了代码:http://www.cnblogs.com/youxin/p/3266617.html(注:原文解法2代码有误)

解法1:以空间换时间

#include <iostream>

using namespace std;

int main()
{
    int L, M, i, start, end, count;
    bool trees[10001];
    for (i = 0; i < 10001; i++)
        trees[i] = true;
    count = 0;
    cin >> L >> M;
    for (i = 0; i < M; i++){
        cin >> start >> end;
        while (start <= end){
            trees[start] = false;
            start++;
        }
    }
    for (i = 0; i <= L; i++)
        if(trees[i] == true)
            count++;
    cout << count;

    return 0;
}

如何马路长度L极大,比如40亿,以至于无法开设这么大的数组空间,此种解法就失效了。此时可以用解法2:先对区间按照开始时间start升序排列,然后当其他区间start小于初始区间(用temp表示)end时,表明这两个区间有重合,合并之(及修改temp.end)。由于按照区间起始start排序过了,只要start不小于初始区间end,则后面的区间就没有与初始区间重叠的区间了,此时将temp区间长度加到count上,并且将temp变为和前面区间无重叠的新区间,继续向下扫描。

解法2:区间合并

#include <stdio.h>
#include <stdlib.h>
#define M_MAX 100+1
typedef struct Area{
    int start;
    int end;
}Area;

int CompareArea(const void *a, const void *b)
{
    return ((Area *)a)->start - ((Area *)b)->start;
}

int main()
{
    Area area[M_MAX], temp;
    int L, M, count = 0;
    scanf("%d%d", &L, &M);
    for (int i = 0; i < M; i++){
        scanf("%d%d", &area[i].start, &area[i].end);
    }
    qsort(area, M, sizeof(Area), CompareArea);  //区间按照开始时间升序排列

    temp = area[0];
    for (int i = 1; i < M; i++){
        if (area[i].start <= temp.end){
            if(area[i].end > temp.end)
                temp.end = area[i].end;
        }
        else{
            count += temp.end - temp.start + 1;
            temp = area[i];
        }
    }
    count += temp.end - temp.start + 1;
    printf("%d", L+1-count);
    return 0;
}

编程之美也有类似的这个题目,其实,种树问题本质是区间重合判断。

一,问题:

       1. 给定一个源区间[x,y]和N个无序的目标区间[x1,y1] [x2,y2] ... [xn,yn],判断源区间[x,y]是不是在目标区间内。

       2. 给定一个窗口区域和系统界面上的N个窗口,判断这个窗口区域是否被已有的窗口覆盖。

第一题源代码:

按照编程之美给出的提示。 先用区间的左边界值对目标区间进行排序O(nlogn),对排好序的区间进行合并O(n),对每次待查找的源区间,用二分查出其左右两边界点分别处于合并后的哪个源区间中O(logn),若属于同一个源区间则说明其在目标区间中,否则就说明不在。(为什么可以二分法)

原文地址:https://www.cnblogs.com/bohaoist/p/4604652.html