区间重合判断、百度之星题解之重叠区间大小
来源:互联网 发布:php日志系统 编辑:程序博客网 时间:2024/06/05 19:53
题一:
给定一个源区间[x,y]和N个无序的目标区间[x1,y1] [x2,y2] ... [xn,yn],判断源区间[x,y]是不是在目标区间内。
方法一
先用区间的左边界值对目标区间进行排序O(nlogn),对排好序的区间进行合并O(n),对每次待查找的源区间,用二分查出其左右两边界点分别处于合并后的哪个源区间中O(logn),若属于同一个源区间则说明其在目标区间中,否则就说明不在。
http://blog.csdn.net/tianshuai1111/article/details/7828961#comments
#include <iostream>#include <algorithm>using namespace std;struct Line{int low, high;bool operator<(const Line &l) const{return low<l.low;}};#define MAXN 10001Line lines[MAXN];// 目标区间int ncnt = 0;// 合并后区间的个数#define N 101Line sl[N];// 待查询的源区间// 用二分查找找出key所在的区间,以区间的low作为划分int GetIndex(int key){int u, v;u = 0; v = ncnt-1;while (u<=v)// u,v可取等号{int m = (u+v)>>1;if (key >= lines[m].low)u = m+1;elsev = m-1;}return v;}int main(){int n, k, i, j;cin >> n >> k;// n是目标区间的个数,k是待查询的源区间的个数for (i=0; i<n; i++)cin >> lines[i].low >> lines[i].high;for (i=0; i<k; i++)cin >> sl[i].low >> sl[i].high;// 排序O(nlogn)sort(lines, lines+n);// 合并O(n)int lasthigh = lines[0].high;for (i=1; i<n; i++)if (lasthigh >= lines[i].low)lasthigh = lines[i].high;else{lines[ncnt++].high = lasthigh;lines[ncnt].low = lines[i].low;lasthigh = lines[i].high;}lines[ncnt++].high = lasthigh;for (i=0; i<k; i++){// 单词查找时间O(logn)int s1 = GetIndex(sl[i].low);int s2 = GetIndex(sl[i].high);if (s1==s2 && sl[i].high <= lines[s2].high)printf("Yes\n");elseprintf("No\n");}}
方法二
#include<iostream>#include<cstdio>using namespace std;const int len=100;int father[len];void make_set(){ for(int i=0;i<len;i++){ father[i]=i; }}int find(int x){ int r=x; while(r!=father[r]){ r=father[r]; } int i=x; while(i!=father[i]){ int j=father[i]; father[i]=r; i=j; } return r;}void merge(int a,int b){ int ra=find(a); int rb=find(b); if(ra!=rb){ father[ra]=rb; }}int main(void){ freopen("a.txt","r",stdin); int x1,y1; cin>>x1>>y1; int n; cin>>n; make_set(); while(n--){ int x,y; cin>>x>>y; for(int i=x+1;i<=y;i++){ merge(x,i); } } if(find(x1)==find(y1)){ cout<<"yes"<<endl; }else{ cout<<"no"<<endl; } 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 18],其大小为9;行(20 10)和(20 30)的重叠区间大小为1。
输入数据:程序读入已被命名为input.txt的输入数据文本文件,该文件的行数在1到1,000,000之间,每行有用一个空格分隔的2个正整数,这2个正整数的大小次序随机,每个数都在1和2^32-1之间。(为便于调试,您可下载测试input.txt文件,实际运行时我们会使用不同内容的输入文件。)
输出数据:在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出0。
评分标准:程序输出结果必须正确,内存使用必须不超过256MB,程序的执行时间越快越好。
思路:#include<iostream>#include<cstdio>#include<fstream>#include<vector>#include<algorithm>using namespace std;struct cmp{ bool operator()(const pair<int,int>& a,const pair<int,int>& b)const{ return a.first<b.first; }};int main(){ ifstream in("a.txt"); vector<pair<int,int> >vec; int a,b; while(in>>a>>b){ if(a>b){ swap(a,b); } vec.push_back({a,b}); } sort(vec.begin(),vec.end(),cmp()); int maxCover=0; int lastEnd=vec[0].second; int len=vec.size(); for(int i=1;i<len;i++){ int right=min(lastEnd,vec[i].second); int cover=right-vec[i].first>=0?right-vec[i].first+1 : 0; if(cover>maxCover){ maxCover=cover; } if(vec[i].second>lastEnd){ lastEnd=vec[i].second; } } cout<<maxCover<<endl; return 0;}
- 区间重合判断、百度之星题解之重叠区间大小
- [百度之星] 2005年百度之星程序大赛初赛题目(重叠区间大小)
- 编程之美-区间重合判断
- 《编程之美》 2.19 区间重合判断
- 编程之美 2.19 区间重合判断
- 【编程之美】区间重合判断
- 编程之美2.19区间重合判断
- 编程之美区间重合判断
- 区间重合判断-编程之美2.19
- 【编程之美】区间重合判断
- 编程之美 2.19 区间重合判断
- 编程之美区间重合判断
- [编程之美]区间重合判断
- 编程之美 - 区间重合判断
- 读书笔记之编程之美 - 2.19 区间重合判断
- 【编程之美】区间重合判断(线段树)
- 编程之美——2.19 区间重合判断
- 区间重合判断(编程之美2.19)
- MVC4数据注解和验证
- iOS 如何在一个存在多个project的workspace中引入cocoapods管理第三方类库
- 【CodeForces】597A - Divisibility(容斥原理,数学)
- H5无插件范式
- 关于VMware克隆的linux虚拟机eth0网卡无法正常启动的问题
- 区间重合判断、百度之星题解之重叠区间大小
- c语言字符数组与字符串的使用详解
- [SIM] MT6589 W+G/G+G dual-talk找不到SIM卡2
- springmvc 获取request response
- Linux资源监控工具
- 欧几里得距离转换(EDT)算法
- D3.js学习02_数据绑定data
- Android BLE 中心和外设通信时 中心设备的onCharacteristicChanged() 没有回调
- 城市选择下拉菜单三级联动