/* -------------------------------------------- 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 ; }