区间重合判断
题目大意:
输入两个表示区间范围的整数[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"); }