最大间隔问题
2018-03-22 09:07
155 查看
问题描述
给定n个实数x1, x2, x3, … , xn, 求这n个数在实轴上相邻2个数之间的最大间隔。假设对任何实数取整耗时O(1), 设计解最大间隙问题的线性时间算法。算法设计
对于给定的n个实数x1, x2, x3, … , xn, 计算它们的最大间隙。数据输入
输入数据由文件名为input.txt的文本文件提供,文件的第1行有1一个正整数n, 接下来1行中有n个实数x1, x2, x3, … , xn。数据输出
将找到的最大间隔输出到文件output.txt样例
输入:5
2.3 3.1 7.5 1.5 6.3
输出:
3.2
算法实现分析
本问题可以运用鸽巢原理进行解答。其具体实现步骤如下:找出n个实数中的最大值n_max 和 最小值n_min
申请n+1个盘子,并记录每一个盘子中的元素个数、上下界
将[n_min, n_max]划分成n-1个等长区间,第一个盘子只放最小值,最后一个盘子只放最大值,剩余n-1个盘子用来存放n-2个数。很明显,必然至少有一个盘子没有存放任何数。因此,最大间隔存在于空盘子的两侧。
线性查找出最大间隔。
实现代码
#include <iostream> #include <fstream> #include <cstring> #include <math.h> using namespace std; #define infilePath "./input.txt" #define outFilePath "./output.txt" int main(int argc, char**argv) { int Nums; float n_max; float n_min; ifstream infile; ofstream outfile; infile.open(infilePath, ios::in); outfile.open(outFilePath, ios::out); if (!infile.is_open()) cout << "open file failure" << endl; if (!outfile.is_open()) cout << "open file failure" << endl; while (infile >> Nums) { float * number = new float[Nums]; float maxInterval = 0; //读入数据 并 找到最大值和最小值 for (int i = 0; i < Nums; i++) { infile >> number[i]; if (i == 0) { n_max = number[0]; n_min = number[0]; continue; } if (number[i]>n_max) { n_max = number[i]; } if (number[i] < n_min) { n_min = number[i]; } } //申请记录每一个盘子的元素个数和其上下界 第一个盘子 只放最小值 最后一个盘子只放最大值 int* count = new int[Nums + 1]; float* upperBound = new float[Nums + 1]; float* lowerBound = new float[Nums + 1]; for (int i = 1; i < Nums; i++) { count[i] = 0; upperBound[i] = n_min; lowerBound[i] = n_max; } count[0] = 1; count[Nums] = 1; upperBound[0] = n_min; lowerBound[0] = n_min; upperBound[Nums] = n_max; lowerBound[Nums] = n_max; //将n-2个数放入 n-1个盘子中 for (int i = 0; i < Nums; i++) { if (number[i] == n_max || number[i] == n_min) continue; int index = floor((number[i] - n_min)*(Nums - 1) / (n_max - n_min)) + 1; // 下标取值范围 1 到 n-1 if (number[i]>upperBound[index]) { upperBound[index] = number[i]; } if (number[i] < lowerBound[index]) { lowerBound[index] = number[i]; } count[index] ++; } //线性查找最大间隔 存在于count=0 的两侧 for (int i = 1; i < Nums; i++) { int tmp; float gap; if (count[i]>0) continue; else { tmp = i; while (!count[i]) i++; gap = lowerBound[i] - upperBound[tmp - 1]; } if (gap > maxInterval) maxInterval = gap; } //输出结果 outfile << maxInterval<< endl; } //关闭文件 infile.close(); outfile.close(); }
测试结果
输入:5
5.1 5.2 5.3 5.39 5.9
5
2.3 3.1 7.5 1.5 6.3
3
1.08 1.090 1.80
输出:
0.51
3.2
0.71
相关文章推荐
- 支持向量机(SVM)关键点攻略(最大间隔,对偶问题)
- 【机器学习-西瓜书】六、支持向量机(SVM):最大间隔;对偶问题;KKT条件
- 【Killua笔试面试题整理】最大间隔问题
- BLE 连接间隔最大值和最小值的问题
- 第7节-最大间隔分类和对偶问题
- HDU 1864 最大报销额 背包问题
- 8.最大公约数和最小公倍数问题
- 【网络流24题】No.11(航空路线问题 最长不相交路径 最大费用流)
- 数组中球子数组和最大的问题(结对开发)
- Dropbox 最大的问题:移动战略缺位
- [cogs729]圆桌问题(最大流)
- NSDate,NSString相互转换,解决八小时间隔问题
- 连续子序列最大和问题精讲(java实现)
- 解决WCF接口超时无响应 最大连接数问题
- 最大连续子序列和问题(Maximum Consecutive Subsequence Sum)
- 最大子序列和问题
- 网络流24题(07)试题库问题(二分图多重匹配 + 最大流)
- 【算法】最大子段和问题
- 最大子序列和问题求解 algorithm 1 O(N^3)
- 股票最大收益问题及数组最大差值问题