编程之美区间重合判断
来源:互联网 发布:下载淘宝app官方软件 编辑:程序博客网 时间:2024/05/17 05:56
一,问题:
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)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;}
方法二:并查集
#include <iostream>using namespace std;const int size = 100;int faher[size];//我们用正负区分根节点//负表示根节点,负数表示集合中的个数//正数表示子节点,father[i]表示父亲的索引void MakeSet(int len)//-1表示集合中的个数为1{for(int i=0; i<len; i++){faher[i] = -1;//初识化,大家独自一个集体}}int Find(int x){if(faher[x]>=0)return Find(faher[x]);elsereturn x;}void Union(int x,int y){int xRoot = Find(x);int yRoot = Find(y);int temp;if(xRoot != yRoot){ temp = faher[xRoot] + faher[yRoot];if(faher[xRoot]<faher[yRoot]){//说明x的子节点多余y的子节点,避免生产退化树faher[xRoot] = temp;faher[yRoot] = xRoot;}else{faher[yRoot] = temp;faher[xRoot] = yRoot;}}}void PrintSet(int len){cout<<"Set:";for(int i=0; i<len; i++)cout<<faher[i]<<" ";cout<<endl;}int main(){ int n;cin>>n; //区间的个数 MakeSet(20);PrintSet(20);while(n--){ int x,y;cin>>x>>y; //输入每个区间 if(x>y){//这一步很关键,表示考虑的周到 swap(x, y); } for(int i=x+1; i<=y; i++){//将区间内的 段合并到已有区间 Union(x,i); } PrintSet(20);} int x1, y1; cin>>x1>>y1;//输入要判断区间 if(Find(x1) == Find(y1)){ cout<<"yes"<<endl; } else{ cout<<"no"<<endl; } system("pause"); return 0;}
这里贴一道百度的题目:题目描述:请编写程序,找出下面“输入数据及格式”中所描述的输入数据文件中最大重叠区间的大小。对一个正整数n,如果n在数据文件中某行的两个正整数(假设为A和B)之间,即A<=n<=B或A>=n>=B,则n属于该行;如果n同时属于行i和j,则i和j有重叠区间;重叠区间的大小是同时属于行i和j的整数个数。
例如,行(10 20)和(12 25)的重叠区间为[12 20],其大小为9;行(20 10)和(12 18)的重叠区间为[10 12],其大小为3;行(20 10)和(20 30)的重叠区间大小为1。
答案:解法1先排序+判断重复的区间http://www.cnblogs.com/absolute8511/archive/2009/05/13/1649584.html
解法2:用位图,int bitmap[len],对将每个区间写入位图,位图相应位置加1操作,bitmap[pos]++,最后统计大于的区域且连续的区域的长度最大值。就向下图所示,区域的计数为1表示有但是没有重叠,0表示该区间没有被覆盖到,2表示有个区间覆盖到,3表示有3个区间覆盖到,4表示有4个区间覆盖到。我们只有判断大于1区域长度的最大值,下图中明显为4区域。
________________________________________________________________________
|______1_____|______2______|____3____|____0____|_______4_________________|
解法3:线段树。
- 编程之美-区间重合判断
- 《编程之美》 2.19 区间重合判断
- 编程之美 2.19 区间重合判断
- 【编程之美】区间重合判断
- 编程之美2.19区间重合判断
- 编程之美区间重合判断
- 区间重合判断-编程之美2.19
- 【编程之美】区间重合判断
- 编程之美 2.19 区间重合判断
- 编程之美区间重合判断
- [编程之美]区间重合判断
- 编程之美 - 区间重合判断
- 读书笔记之编程之美 - 2.19 区间重合判断
- 【编程之美】区间重合判断(线段树)
- 编程之美——2.19 区间重合判断
- 区间重合判断(编程之美2.19)
- 编程之美--区间重合判断
- 编程之美——区间重合判断
- gcc编译c语言的uint问题
- 这是要把前几年积累的C++的节操给丢光吗
- Java学习总结之贪吃蛇项目程序编写(完结)
- Linux系统调用
- Windows 7系统下, 使用VC编译OpenSSL静态库步骤
- 编程之美区间重合判断
- 编程之美1.1让CPU占用率曲线听你指挥之解法一细节
- 值得拥有
- STL中的vector
- 二叉树的非递归遍历
- 在一些随机的位置嵌入噪声帧
- 教你如何成为数据科学家(六)
- git 的安装和配置
- 为eCos安装扩展组件包