hdu 2141 二分查找
直接枚举Ai, Bj, Ck的复杂度为L×M×N,过不了。先把所有Ai, Bj的和存起来并排序,然后枚举Ck,二分查找Ai, Bj的和,复杂度为L×M×log(L×M)。
/*
* hdu2141/linux.cpp
* Created on: 2011-9-1
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 510;
int L, N, M, LM;
int A[MAXN], B[MAXN], C[MAXN], sum[MAXN * MAXN];
bool find(int num) {
int mid, low, high;
low = 0;
high = LM - 1;
while (low <= high) {
mid = (low + high) / 2;
if (sum[mid] == num) {
return true;
} else if (sum[mid] > num) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low < LM && sum[low] == num;
}
bool search(int x) {
for (int i = 0; i < N; i++) {
if (find(x - C[i])) {
return true;
}
}
return false;
}
void work();
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
work();
return 0;
}
void work() {
int T = 0, S, x;
while (scanf("%d%d%d", &L, &M, &N) == 3) {
for (int i = 0; i < L; i++) {
scanf("%d", &A[i]);
}
for (int i = 0; i < M; i++) {
scanf("%d", &B[i]);
}
for (int i = 0; i < N; i++) {
scanf("%d", &C[i]);
}
scanf("%d", &S);
sort(A, A + L);
sort(B, B + M);
sort(C, C + N);
printf("Case %d:\n", ++T);
LM = 0;
for (int i = 0; i < L; i++) {
for (int j = 0; j < M; j++) {
sum[LM++] = A[i] + B[j];
}
}
sort(sum, sum + LM);
while (S--) {
scanf("%d", &x);
if (search(x)) {
puts("YES");
} else {
puts("NO");
}
}
}
}