二分查找 UVa 10487 - Closest Sums,时间复杂度为O(2nlogn)
2013-06-20 13:31
561 查看
思路:
设给定的数为q,找出数组中的两个不相同的数(值可以相同)a、b,满足MIN{|q-(a+b)|},当q-a=b时,得到最小值为0。
所以,可以先将数组排序,遍历a为数组中的数,二分查找数组中与q-a最为接近的数即为b。
排序和遍历的时间复杂度为均为O(nlogn)。
设给定的数为q,找出数组中的两个不相同的数(值可以相同)a、b,满足MIN{|q-(a+b)|},当q-a=b时,得到最小值为0。
所以,可以先将数组排序,遍历a为数组中的数,二分查找数组中与q-a最为接近的数即为b。
排序和遍历的时间复杂度为均为O(nlogn)。
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; #define MAXN 1005 #define INF 0x7FFFFFFF int a[MAXN]; int BSearch(int low, int high, int targ) { if (targ <= a[low]) { return low; } if (targ >= a[high]) { return high; } while (low <= high) { int mid = (low + high) / 2; if (targ == a[mid]) { return mid; } else if (targ < a[mid]) { high = mid - 1; } else { low = mid + 1; } } return (targ - a[high]) < (a[low] - targ) ? high : low; } int ClosestSum(int n, int q) { int closestSum, minDiff = INF; int i, j; for (i = 0; i < n-1; i++) { j = BSearch(i+1, n-1, q-a[i]);//查找范围[i+1,n-1],去除重复结果,如i=1,j=2和i=2,j=1重复 if (abs(a[i]+a[j]-q) < minDiff) { closestSum = a[i] + a[j]; minDiff = abs(a[i]+a[j]-q); } } return closestSum; } int main(void) { int n, m, caseID = 1; while (scanf("%d", &n) != EOF) { if (n == 0) { break; } int i; for (i = 0; i < n; i++) { scanf("%d", &a[i]); } sort(a, a+n); printf("Case %d:\n", caseID++); scanf("%d", &m); for (i = 0; i < m; i++) { int q; scanf("%d", &q); printf("Closest sum to %d is %d.\n", q, ClosestSum(n, q)); } } return 0; }
相关文章推荐
- uva:10487 - Closest Sums(二分查找)
- UVA 10487 Closest Sums (二分查找)
- UVA - 10487 Closest Sums(二分查找)
- uva - 10487 - Closest Sums(二分查找)
- uva:10487 - Closest Sums(二分查找)
- UVA 10487 Closest Sums(二分)
- UVA - 10487 - Closest Sums (二分求解)
- uva 10487 Closest Sums(二分搜索)
- uva 10487 Closest Sums (遍历&二分查找&&双向查找)
- 彻底轻松搞定顺序存储结构元素的二分查找的时间复杂度优势以及如何算时间复杂度
- 【二分查找】在一个长度未知的数组中查找一个数,返回其下标,时间复杂度O(logn)
- 二分查找以及二分查找的时间复杂度
- UVa 10487 Closest Sums (遍历&二分查找)
- UVA 10487 Closest Sums(水)
- uva10487 - Closest Sums
- 二分查找时间复杂度分析
- uva 10487 - Closest Sums
- POJ2533, 最长上升子序列(贪心+二分查找时间复杂度O(nlogn))
- 二分查找及其时间复杂度
- 二分查找时间复杂度计算与分析