zoukankan      html  css  js  c++  java
  • 区间重合判断[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),若属于同一个源区间则说明其在目标区间中,否则就说明不在。(为什么可以二分法)

  • 相关阅读:
    Oracle EBS-SQL (BOM-17):检查8层BOM.sql
    Oracle EBS-SQL (BOM-16):检查多层BOM.sql
    Oracle EBS-SQL (BOM-15):检查多层BOM(含common BOM).sql
    Oracle EBS-SQL (OM-1):查询订单发货明细.sql
    Oracle EBS-SQL (BOM-14):检查工艺路线明细.sql
    Oracle EBS-SQL (PO-14):检查供应商信息sql
    Oracle EBS-SQL (PO-13):检查采购物料无一揽子协议价格.sql
    Oracle EBS-SQL (INV-7):检查接收中记录数.sql
    Oracle EBS-SQL (INV-6):检查监督帐户别名处理.sql
    Oracle EBS-SQL (PO-12):检查期间请购单的下达记录数.sql
  • 原文地址:https://www.cnblogs.com/bohaoist/p/4604652.html
Copyright © 2011-2022 走看看