您的位置:首页 > 其它

uva - 10487 - Closest Sums(二分查找)

2014-02-07 21:33 387 查看
题意:给你一些数,两两的话可以组成很多和,在给你一些其他的数,找前边算出来的和中最接近后边这些数的和。

方法:求和,排序去重,二分查找。

注意: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排序,程序大改后没注意。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: