题目(二分查找)
给三组整数,在下面每给一个整数,判断从三组数各取一个相加与此整数是否可以相等。
解题思路
将A数组和B数组先“相加”(不是按位相加,因为他们的长度可能不同。而是弄两个for循环,将他们所有能相加的组合都尝试一边)成一个数组AB[500*500]。这样就相当于AB[i] + C[j] = x。 再变形一下, AB[i] = x - C[j]. 这样只要在AB数组中用二分查找是否存在x-C[j]就可以了。
样例
样例输入
3 3 3
1 2 3
1 2 3
1 2 3
3
1
4
10
样例输出
Case 1:
NO
YES
NO
AC代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
int A[501];
int B[501];
int C[501];
__int64 AB[501 * 501];
int len;
int erfen(int x)
{
int low = 0, high = len - 1;
while (high >= low)
{
int mid = (high + low) / 2;
if (AB[mid] < x)
low = mid + 1;
else if (AB[mid] > x)
high = mid - 1;
else
return mid;
}
return 0;
}
int main()
{
int a, b, c, S, x, p = 0;
while (cin >> a >> b >> c)
{
for (int i = 0; i < a; i++)
cin >> A[i];
for (int i = 0; i < b; i++)
cin >> B[i];
for (int i = 0; i < c; i++)
cin >> C[i];
int k = 0;
for (int i = 0; i < a; i++)
for (int j = 0; j < b; j++)
AB[k++] = A[i] + B[j]; // 要在两个for循环中相加,满足他们所有能相加的组合
len = k;
sort(AB, AB + len);
//更好的方法:对C也排序。然后在下面多加一个判断
sort(C, C + c);
cout << "Case " << ++p << ":" << endl;
cin >> S;
for (int i = 0; i < S; i++)
{
cin >> x;
if (x < AB[0] + C[0] || x > AB[len - 1] + C[c - 1])
{
cout << "NO" << endl;
continue;
}
int flag = 0;
for (int j = 0; j < c; j++)
{ // 对于每一个x,都需要遍历一遍C数组
if (erfen(x - C[j]) != 0)
{
cout << "YES" << endl;
flag = 1;
break; //查找到一个解后就立马退出
}
}
if (!flag)
{
cout << "NO" << endl;
}
}
}
}