【数字题3】最大重叠子区间
2013-05-13 20:32
239 查看
问题描述
对一个正整数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 8)的重叠区间为[10 12],其大小为3;行(20 10)和(20 30)的重叠区间大小为1。
输入数据:程序读入已被命名为input.txt的输入数据文本文件,该文件的行数在1到1,000,000之间,每行有用一个空格分隔的2个正整数,这2个正整数的大小次序随机,每个数都在1和2^32-1之间。
输出数据:在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出0。
解题思路
定义下界为区间的左端,上界为区间的右端。对每个区间的下界从小到大进行排序,若两个区间的下界相同,则按上界从小到大进行排序。定义一个max_overlap=0存放当前得到的最大重叠区间,之后顺序处理,假设区间存放在一个结构体里,定义如下:
如果regins[i].left<regins[i-1].right,说明这两个区间相交,分为两种情况:
1、regins[i-1].right>regins[i].right
2、regins[i-1].right<regins[i].right
综合上述两种情况,令right_small=min(regins[i].right,regins[i1].right),找出两个线段上界较小的那个,得到相交区间为right_small-regins[i].left+1,如果该值大于max_overlap,则更新max_overlap。
考虑下面一种情况:
regins[i-1]的上界大于regins[i]的上界,需要将regins[i-1]的上界替换给regins[i],就是上图的红色线段部分,然后regins[i]再与regins[i-1]求相交区间,其实也好理解,当regins[i]包含在上一段时,我实际希望比较的是regins[i+1]与regins[i-1],但这个时候,并不关心比regins[i-1].left小的那部分。
令right_big=max(regins[i].right,regins[i-1].right),找出两个线段中上界较大的那个,把b的值赋给regins[i].right,继续下一步的处理。
排序的时间复杂度为O(nlogn),比较更新的复杂度为O(n),总的复杂度为O(n)
程序实例
<soon>
对一个正整数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 8)的重叠区间为[10 12],其大小为3;行(20 10)和(20 30)的重叠区间大小为1。
输入数据:程序读入已被命名为input.txt的输入数据文本文件,该文件的行数在1到1,000,000之间,每行有用一个空格分隔的2个正整数,这2个正整数的大小次序随机,每个数都在1和2^32-1之间。
输出数据:在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出0。
解题思路
定义下界为区间的左端,上界为区间的右端。对每个区间的下界从小到大进行排序,若两个区间的下界相同,则按上界从小到大进行排序。定义一个max_overlap=0存放当前得到的最大重叠区间,之后顺序处理,假设区间存放在一个结构体里,定义如下:
struct regins{ int left;//区间上界 int right;//区间下界 }
如果regins[i].left<regins[i-1].right,说明这两个区间相交,分为两种情况:
1、regins[i-1].right>regins[i].right
2、regins[i-1].right<regins[i].right
综合上述两种情况,令right_small=min(regins[i].right,regins[i1].right),找出两个线段上界较小的那个,得到相交区间为right_small-regins[i].left+1,如果该值大于max_overlap,则更新max_overlap。
考虑下面一种情况:
regins[i-1]的上界大于regins[i]的上界,需要将regins[i-1]的上界替换给regins[i],就是上图的红色线段部分,然后regins[i]再与regins[i-1]求相交区间,其实也好理解,当regins[i]包含在上一段时,我实际希望比较的是regins[i+1]与regins[i-1],但这个时候,并不关心比regins[i-1].left小的那部分。
令right_big=max(regins[i].right,regins[i-1].right),找出两个线段中上界较大的那个,把b的值赋给regins[i].right,继续下一步的处理。
排序的时间复杂度为O(nlogn),比较更新的复杂度为O(n),总的复杂度为O(n)
程序实例
<soon>
相关文章推荐
- Spoj 1557 Can you answer these queries II 线段树 任意区间最大子段和 不重复数字
- 将[1,n^2]区间内n^2个数字分别填充到n*n的矩阵里,要求任意两个相邻的数字的和,它们的最大值最小是多少?
- noip2013 小朋友的数字 (最大子区间和+动态规划)
- Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字
- 今日头条笔试题:“最小数字*区间和”的最大值【单调栈】
- 连续最大和,数字类区间问题
- 线段树(单点更新,区间求最大值)
- 【HDU5751 BestCoder Round 84E】【FFT + 线段树求最值】Eades 最大数出现次数为[1~n]的区间个数
- 背包算法练习--求小于某数字的数组最大和:
- 给一个整数数组,对数组中的每个整数中的所有数字按照升序排列(如101排序后为011)请写一个方法,输出排序后的数组中的最大数。 例如有一个数组: 101、132、375,排序后11、123、357,
- EOJ 3367/FOJ 2253咸鱼翻身【最大区间和】
- 给定一串数字求连续的最大和
- 九度数字序列区间最小值
- 输入数字n,按顺序打印出1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。
- HDOJ 1754 I Hate It 【线段树节点更新&&求区间最大值】
- 最大连续区间和问题 —— 转自purplest C++博客
- hdu3415 单调队列求区间最大和
- HDU 3530 Subsequence(区间最值差>=m且<=k的最大长度、双单调队列)
- 输入一个字符串只包含“0~10”和”,“找出最小的数字和最大的数字(可能不止一个),输出最后剩余数字的个数,如输入”3,3,4,5,6,7,7“
- 算法训练1.区间k最大数查询(排序 查找)