zoukankan      html  css  js  c++  java
  • 区间重合判断

    题目:给定一些无序区间,判断某个给定的特定区间是否在这些无序的区间内。
    这个题目比较简单,首先将给定的区间排序,在对重合的区间进行排序,使得区间变成递增且不重叠的若干个区间,对于给定的区间在已经处理好的区间内进行二分查找,完成区间覆盖的判断。
    程序如下:

    [cpp] view plaincopy

    1. #include <stdio.h>  
    2. #include <vector>  
    3. #include <algorithm>  
    4. class Interval {  
    5.  public:  
    6.   Interval(int start, int end) : start_(start), end_(end) {}  
    7.   Interval() :start_(0), end_(0) {}  
    8.   static bool OrderByStart(const Interval& left, const Interval& right) {  
    9.     return left.start_ < right.start_;  
    10. 10.   }  
    11. 11.   friend bool operator<(const Interval& left, const Interval& right) {  
    12. 12.     return left.start_ < right.start_;  
    13. 13.   }  
    14. 14.   int start_;  
    15. 15.   int end_;  

    16. };  

    17. void CombinInterval(std::vector<Interval>& orginal, std::vector<Interval>* combined) {  

    1. 18.   if (orginal.size() < 1) {  
    2. 19.     return;  
    3. 20.   }  
    4. 21.   sort(orginal.begin(), orginal.end(), Interval::OrderByStart);  
    5. 22.   Interval combined_interval = orginal[0];  
    6. 23.   int new_ending = orginal[0].end_;  
    7. 24.   for (int i = 1; i < orginal.size(); ++i) {  
    8. 25.     if (combined_interval.end_ >= orginal[i].start_) {  
    9. 26.       new_ending = combined_interval.end_ > orginal[i].end_ ? combined_interval.end_ : orginal[i].end_;  
    10. 27.       continue;  
    11. 28.     }  
    12. 29.     combined_interval.end_ = new_ending;  
    13. 30.     combined->push_back(combined_interval);  
    14. 31.     combined_interval = orginal[i];  
    15. 32.     new_ending = orginal[i].end_;  
    16. 33.   }  
    17. 34.   combined_interval.end_ = new_ending;  
    18. 35.   combined->push_back(combined_interval);  

    36. }  

    37. bool CoverTest(const Interval& interval, std::vector<Interval>& intervals, Interval* covered_interval) {  

    1. 38.   std::vector<Interval> combined_intervals;  
    2. 39.   CombinInterval(intervals, &combined_intervals);  
    3. 40.   for (int i = 0; i < combined_intervals.size(); ++i) {  
    4. 41.     printf("%d-%d ", combined_intervals[i].start_, combined_intervals[i].end_);  
    5. 42.   }  
    6. 43.     
    7. 44.   if (combined_intervals.size() < 1) {  
    8. 45.     return false;  
    9. 46.   }  
    10. 47.   int start = 0;  
    11. 48.   int end = combined_intervals.size() -1;  
    12. 49.   int middle = 0;  
    13. 50.   bool found = false;  
    14. 51.   while (end >= start) {  
    15. 52.     middle = (start + end) / 2;  
    16. 53.     if (interval < combined_intervals[middle]) {  
    17. 54.       end = middle - 1;  
    18. 55.     } else if (combined_intervals[middle] < interval) {  
    19. 56.       start = middle + 1;  
    20. 57.     } else {  
    21. 58.       found = true;  
    22. 59.       break;        
    23. 60.     }  
    24. 61.   }  
    25. 62.   int target_index = found ? middle : start - 1;  
    26. 63.   printf("target:%d ", target_index);  
    27. 64.   if (target_index >= 0 &&  
    28. 65.       combined_intervals[target_index].start_ <= interval.start_ &&  
    29. 66.       combined_intervals[target_index].end_  >= interval.end_) {  
    30. 67.     *covered_interval = combined_intervals[target_index];  
    31. 68.     return true;  
    32. 69.   } else {  
    33. 70.     return false;  
    34. 71.   }  

    72. }    

    73. int main(int argc, char** argv) {  

    1. 74.   std::vector<Interval> intervals;  
    2. 75.   intervals.push_back(Interval(2,5));  
    3. 76.   intervals.push_back(Interval(3,4));  
    4. 77.   intervals.push_back(Interval(4,7));  
    5. 78.   intervals.push_back(Interval(9,13));  
    6. 79.   Interval target_interval(3, 4);  
    7. 80.   Interval covered_interval;  
    8. 81.   if (CoverTest(target_interval, intervals, &covered_interval)) {  
    9. 82.     printf("the covered interval is (%d, %d) ", covered_interval.start_, covered_interval.end_);  
    10. 83.   } else {  
    11. 84.     printf("uncovered ");  
    12. 85.   }  

    86. }  

     

    程序编写时开始犯了几个错误:

    1、函数参数开始使用了const 修饰,导致sort时出错

    2、区间合并时,没有将最后一个加入到向量中,new_ending设置的初值也要注意,开始就出错了

    3、二分查找,找下界时,需要将查找过程走几遍就比较清楚了,下界是start-1,但如果start为0,下界可能是负数,要注意处理。另外循环条件是start <=end,等号也很重要,如果判断过程中只有一个元素时,就是等号覆盖的情况。

    题目大意:

    输入两个表示区间范围的整数[x,y]

    然后输入N个无序区间[x1,y1], [x2, y2], [x3, y3]...

    求解第一次输入的区间是否在N个无序区间组合成的大区间中。

     

    法一:使用并查集,对每个区间合并到一个子树上,最后判断源区间的x和y的根是否相同。

    View Code

     

    #include<iostream>

    using namespace std;

     

    const int size = 100;

    int father[size];

    int rank[size];

     

    void make_set(int n)

    {

        for(int i = 1; i <= n; i ++){

            father[i] = i;   

            rank[i] = 1;

        }   

    }

     

    int find_set(int x)

    {

        if(x != father[x]){

            father[x] = find_set(father[x]);   

        }   

        return father[x];

    }

     

    void Union(int x, int y)

    {

        x = find_set(x);   

        y = find_set(y);

        if(x == y){

            return ;   

        }

        if(rank[x] < rank[y]){

            father[x] = y;   

        }

        else{

            father[y] = x;

            if(rank[x] == rank[y]){

                rank[x] ++;   

            }   

        }

    }

     

    int main()

    {

        int x1, y1;

        cin >> x1 >> y1;

        int x, y;

        int n;

        cin >> n;

        make_set(size);

        while(n --){

            cin >> x >> y;

            if(x > y){

                swap(x, y);   

            }

            for(int i = x + 1; i <= y; i ++){

                Union(x, i);

            }

        }   

        if(find_set(x1) == find_set(y1)){

            cout << "yes" << endl;   

        }

        else{

            cout << "no" << endl;   

        }

        system("pause");

    }

     

    法二:将无序的目标区间排序后,再合并成几个有序的区间,然后把源区间和有序的目标区间比较。

    View Code

     

    #include<iostream>

    #include<vector>

    using namespace std;

     

    typedef pair<int, int> section;

     

    bool cmp(section a, section b)

    {

        return a.first < b.first;   

    }

     

    int main()

    {

        section src, tmp;

        cin >> src.first >> src.second;

       

        vector<section> v;

        while(cin >> tmp.first >> tmp.second, tmp.first | tmp.second){

            v.push_back(tmp);   

        }

       

        sort(v.begin(), v.end(), cmp);

       

        vector<section> res;

        vector<section>::iterator it = v.begin();

        int begin = it->first;

        for(; (it + 1) != v.end(); it ++){

            if(it->second < (it + 1)->first){

                res.push_back(make_pair(begin, it->second));   

                begin = (it + 1)->first;

            }   

        }

       

        bool solve = false;

        it = res.begin();

        for(; it != res.end(); it ++){

            if(src.first >= it->first && src.second <= it->second){

                solve = true;   

                break;

            }   

        }

        if(solve){

            cout << "in" << endl;   

        }

        else{

            cout << "out" << endl;   

        }

        system("pause");

    }

  • 相关阅读:
    JS站点
    1011 World Cup Betting (20分)
    1007 Maximum Subsequence Sum (25分)(动态规划DP)
    1006 Sign In and Sign Out (25分)
    1005 Spell It Right (20分)
    1004 Counting Leaves (30分)(DFS)
    1003 Emergency (25分)(Dijkstra算法)
    1002 A+B for Polynomials (25分)
    1001 A+B Format (20分)
    canvas
  • 原文地址:https://www.cnblogs.com/fickleness/p/3154995.html
Copyright © 2011-2022 走看看