简单题目,先将所有元素从小到大排序,找到第一个比待寻找的和大的数字,从这个数字到第一个数字间的数字进行两两组合,枚举可能的和,找到最接近的一个就行了,在寻找第一个比待寻找的和大的数字的时候,可以二分来找,效率还可以提高一点点,不过重点不在这里,顺序查找也可以ac,注意适当进行剪枝。
#include <stdio.h>
#include <algorithm>
using namespace std;
int arr[1005];
int cmp(const void *a, const void *b)
{
return *((int*)a) - *((int*)b);
}
int _abs(int x)
{
return x<0 ? -1*x:x;
}
void func(int n, int x)
{
int end, sum;
int i, j;
int result;
for(i=0; i<n; i++)
if(arr[i] >= x)
break;
if(i==n)
end = i-1;
else
end = i;
if(end <= 1)
{
result = arr[0] + arr[1];
goto end;
}
result = arr[end] + arr[0];
for(i=end; i>=1; i--)
{
for(j=i-1; j>=0; j--)
{
sum = arr[i]+arr[j];
if(sum == x)
{
result = sum;
goto end;
}
if(_abs(sum-x) < _abs(result-x))
result = sum;
if(sum <= x)
break;
}
}
end:
printf("Closest sum to %d is %d.\n", x, result);
}
int main(void)
{
int n, m, i, x;
int case_count;
//freopen("input.dat", "r", stdin);
case_count = 0;
while(1)
{
case_count ++;
scanf("%d", &n);
if(!n)
break;
for(i=0; i<n; i++)
scanf("%d", arr+i);
qsort(arr, n, sizeof(int), cmp);
printf("Case %d:\n", case_count);
scanf("%d", &m);
for(i=0; i<m; i++)
{
scanf("%d", &x);
func(n, x);
}
}
return 0;
}