/*
--------------------------------------------
stratege : 二分查找
basic step :
int find (int min, int max, int x) // min是已排列的数组的下限,max为上限,x为所要查找的值
{
int mid ;
while (min <= max)
{
mid = (min + max) / 2 ; //折半查找,顾名思义,从中间元素开始进行对比
if (ab[mid] == x) return 1 ;
if (ab[mid] > x) max = mid - 1 ;
if (ab[mid] < x) min = mid + 1 ;
}
return 0 ;
}
URL : http://acm.hdu.edu.cn/showproblem.php?pid=2141 Can you find it?
******************************************************************
Problem : 2141 ( Can you find it? ) Judge Status : Accepted
RunId : 5330614 Language : G++ Author : a312745658
******************************************************************
------------------------------------------------------------------
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std ;
const int MAXN = 505 ;
int L, N, M ;
int a[MAXN], b[MAXN], c[MAXN] ;
int ab[250005] ;
int S, n ;
int cmp (const void *a, const void *b)
{
return *(int *)a - *(int *)b ;
}
int find (int min, int max, int x)
{
int mid ;
while (min <= max)
{
mid = (min + max) / 2 ;
if (ab[mid] == x) return 1 ;
if (ab[mid] > x) max = mid - 1 ;
if (ab[mid] < x) min = mid + 1 ;
}
return 0 ;
}
int main()
{
int i, j, k ;
int cas = 1 ;
int num ;
while (scanf ("%d%d%d", &L, &N, &M) != EOF)
{
num = 0 ;
for (i = 0; i < L; i ++)
scanf ("%d", &a[i]) ;
for (i = 0; i < N; i ++)
scanf ("%d", &b[i]) ;
for (i = 0; i < M; i ++)
scanf ("%d", &c[i]) ;
scanf ("%d", &S) ;
for (i = 0; i < L; i ++) //将2个数组整合成1个数组,使其为2个数组中各个不同元素的和
for (j = 0; j < N; j ++)
ab[num++] = a[i] + b[j] ;
qsort (c, M, sizeof(c[0]), cmp) ;
qsort (ab, num, sizeof (ab[0]), cmp) ; //注意:需对数组进行排序
printf ("Case %d:\n", cas ++) ;
while (S -- && scanf ("%d", &n))
{
bool flag = false ;
for (i = 0; i < M; i ++)
{
if (find (0, num-1, n-c[i])) //n-c[i], 即为ab[i]中的值,对ab[i]进行折半查找
{
flag = true ;
break ;
}
}
if (flag)
printf ("YES\n") ;
else
printf ("NO\n") ;
}
}
return 0 ;
}