一,问题:
1. 给定一个源区间[x,y]和N个无序的目标区间[x1,y1] [x2,y2] ... [xn,yn],判断源区间[x,y]是不是在目标区间内。
2. 给定一个窗口区域和系统界面上的N个窗口,判断这个窗口区域是否被已有的窗口覆盖。
编程之美的解法:首先利用快排没,将区间按照从小到大排序,[2,3][1,2][3,9]-》[1,2][2,3][3,9];然后对排序的区间进行合并;合并后运用二分法查找。
#include <iostream> #include <algorithm> using namespace std; struct Line{ int low,high; Line(int l=0,int h=0):low(l),high(h){} bool operator<(Line & other) { return low<other.low; } }; const int MAX = 100; Line lines[MAX]; //注意咱们搜索的数为刚好小于key的那个值 int BinarySearchLower(Line arr[],int len,int target) { int low = 0; int high = len-1; while(low < high){ int mid = (low + high)/2; if(arr[mid].low>=target)high = mid-1; else low = mid + 1; } return high; } int main() { int n, k, i, j; cin>>n; // n是目标区间的个数,k是待查询的源区间的个数 for (i=0; i<n; i++) cin >> lines[i].low >> lines[i].high; sort(lines, lines+n); int cnt = 0; //合并以后的区间数 int lasthigh = lines[0].high; //合并区间 for(i=1; i<n; i++){ if(lasthigh>=lines[i].low) lasthigh = lines[i].high; else{ lines[cnt].high = lasthigh; lines[++cnt].low = lines[i].low; lasthigh = lines[i].high; } } lines[cnt++].high = lasthigh; Line search = Line(1,6); int sLow = BinarySearchLower(lines,cnt,search.low); int sHigh = BinarySearchLower(lines,cnt,search.high); if(sLow==sHigh && search.high<=lines[sLow].high)//注意要判断 cout<<"Yes"<<endl; else cout<<"No"<<endl; system("pause"); return 0; }
作者:u010064842 发表于2013-9-19 14:13:57 原文链接
阅读:15 评论:0 查看评论