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");
}
}
}
}
posted @ 2011-09-01 13:15  moonbay  阅读(133)  评论(0编辑  收藏  举报