uva - 10487 - Closest Sums(二分查找)
2014-02-07 21:33
387 查看
题意:给你一些数,两两的话可以组成很多和,在给你一些其他的数,找前边算出来的和中最接近后边这些数的和。
方法:求和,排序去重,二分查找。
注意:1、要先求和再去重,如果边求和,再在和里查找重复就不插入的会TLE,本来数据很多,再套一层循环的话代价非常大。2、二分查找不太会,但是先查找,如果正好有和某一个和相等直接返回。如果没有也就是while循环完了以后,检查low和high所指的数和ques[a]的绝对值大小,取小的那个。注意low和high有可能数组越界,如果越界就把他们定在边界上,见代码。
1、宏定义的问题,MAX = 1000+10,但是写了个MAX*MAX ,RE了,因为没打括号。应该 MAX(1000+10)。
2、循环问题。
3、sort应该给temp_sum排序,程序大改后没注意。
方法:求和,排序去重,二分查找。
注意:1、要先求和再去重,如果边求和,再在和里查找重复就不插入的会TLE,本来数据很多,再套一层循环的话代价非常大。2、二分查找不太会,但是先查找,如果正好有和某一个和相等直接返回。如果没有也就是while循环完了以后,检查low和high所指的数和ques[a]的绝对值大小,取小的那个。注意low和high有可能数组越界,如果越界就把他们定在边界上,见代码。
#include <iostream> #include <iomanip> #include <string> #include <cstring> #include <cstdio> #include <queue> #include <stack> #include <algorithm> #include <cmath> using namespace std; #define MAX (1000+10) int m, n, num[MAX], ques[25], temp_sum[MAX*MAX], sum[MAX*MAX], p; void Input() { int i = 0, j = 0; for (i = 0; i < m; i++) cin >> num[i]; cin >> n; for (i = 0; i < n; i++) cin >> ques[i]; } void Cal_Sum() { int i = 0, j = 0, k = 0; for (i = 0; i < m; i++) { for (j = i+1; j < m; j++) { temp_sum[p++] = num[i] + num[j]; } } } void Sum() { int i = 0, j = 1; sum[0] = temp_sum[0]; for (i = 1; i < p; i++) if (temp_sum[i-1] != temp_sum[i]) sum[j++] = temp_sum[i]; p = j; } int BinSearch(int a) { int i = 0; int low = 0, mid = 0, high = p-1, d = 2147482647; while (high >= low) { mid = (high+low)/2; if (sum[mid] == ques[a]) return sum[mid]; else if (ques[a] > sum[mid]) low = mid+1; else high = mid-1; } if (high < 0) high = 0; if (low > p-1) low = p-1; int x = sum[low], y = sum[high]; if (abs(x - ques[a]) > abs(y - ques[a])) return y; else return x; } int main() { #ifdef Local freopen("a.in", "r", stdin); freopen("a.out", "w", stdout); #endif int i = 0, t = 0;; while (cin >> m && m) { memset(num, 0, sizeof(num)); memset(ques, 0, sizeof(ques)); memset(sum, 0, sizeof(sum)); memset(temp_sum, 0, sizeof(temp_sum)); p = 0; Input(); Cal_Sum(); sort(temp_sum, temp_sum+p); Sum(); cout << "Case " << ++t << ":" << endl; for (i = 0; i < n; i++) { cout << "Closest sum to " << ques[i] << " is " << BinSearch(i) << "." << endl; } } }
1、宏定义的问题,MAX = 1000+10,但是写了个MAX*MAX ,RE了,因为没打括号。应该 MAX(1000+10)。
2、循环问题。
3、sort应该给temp_sum排序,程序大改后没注意。
相关文章推荐
- 二分查找 UVa 10487 - Closest Sums,时间复杂度为O(2nlogn)
- 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 (遍历&二分查找)
- uva 10487 - Closest Sums
- UVA - 10487 Closest Sums 暴力
- UVA 10487 Closest Sums(水)
- uva10487 - Closest Sums
- UVA 10487-Closest Sums(遍历水题)
- uva 10341 - Solve It(二分查找水题)
- UVa 10539 (筛素数、二分查找) Almost Prime Numbers
- UVA.10474 Where is the Marble ( 排序 二分查找 )
- UVA 1152 4 Values whose Sum is 0 中途相遇法 二分查找
- UVA10474 Where is the Marble?(二分查找,STL-lower_bound)