编程之美--区间重合判断(并查集求解)

题目大意:

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

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

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

 

我的思路是使用并查集的方法:

 

1. 保存原始范围

2. 对每输入的一个区间使用并查集的方法–i从xi到yi做并查集的插入MakeSet(FindSet(xi),FindSet(i));

3. 输入结束之后通过比较x和y的根是否相同即可。

 

代码如下:

//区间重合判断,并查集求解 //这种求解需要假定输入整数的范围 //在这里假定n<=1000 #include <iostream> const int NUMRANGE = 1001; using namespace std; int rank[NUMRANGE]; int p[NUMRANGE]; inline void InitializeSet() { //point to itself for (int i=0;i<NUMRANGE;++i) p[i] = i; } int FindSet(int x) { if(x != p[x]) p[x] = FindSet(p[x]); return p[x]; } void MakeSet(int x, int y) { if(x == y) return; if (rank[x] > rank[y]) { p[y] = x; } else { p[x] = y; if(rank[x] == rank[y]) ++rank[y]; } } int main() { InitializeSet(); int oriBg,oriEnd,tempBg,tempEnd; cin>>oriBg>>oriEnd; //输入0 0结束输入 while (cin>>tempBg>>tempEnd,tempBg|tempEnd) { if(tempBg >1000 || tempEnd>1000) { cout<<“The number should in range 1-1000″<<endl; continue; } if (tempBg>tempEnd) { int t = tempEnd; tempEnd = tempBg; tempBg = t; } else if(tempBg == tempEnd) continue; else { for (int i = tempBg+1; i<=tempEnd; ++i) MakeSet(tempBg,i); } } if(FindSet(oriBg) == FindSet(oriEnd)) cout<<“In!”<<endl; else cout<<“Out”<<endl; return 0; }

 

再研究一下书中的解法,稍后补充。

 

原文中的第二种解法的stl实现如下(C++库中的sort的效率是比qsort高的!编程珠玑中有性能比较,以后如果用stl排序,尽量选择sort)

#include <iostream> #include <algorithm> #include <utility> #include <vector> using namespace std; typedef pair<int,int>Range; bool cmp(Range &a,Range &b) { return a.first<b.first; } int main() { Range ori,temp; vector<Range>rangeRec; cin>>ori.first>>ori.second; while (cin>>temp.first>>temp.second, temp.first|temp.second) rangeRec.push_back(temp); sort(rangeRec.begin(),rangeRec.end(),cmp); vector<Range>result; vector<Range>::iterator it = rangeRec.begin(); int bg = it->first; for (;(it+1)!=rangeRec.end();) { if(it->second<(it+1)->first) { result.push_back(make_pair(bg,it->second)); bg = (it+1)->first; } ++it; } result.push_back(make_pair(bg,it->second)); it = result.begin(); for (;it!=result.end();++it) { if(ori.first >= it->first && ori.second <= it->second) { cout<<“In!”<<endl; return 0; } } cout<<“Out!”<<endl; return 0; }

 

    原文作者:hitrose27
    原文地址: https://blog.csdn.net/bladecoder/article/details/6326813
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞