Can you find it? HDU-2141 (二分查找模版题)

Description 

Give you three sequences of numbers A, B, C, then we give you a number X. Now you need to calculate if you can find the three numbers Ai, Bj, Ck, which satisfy the formula Ai+Bj+Ck = X. 

Input

There are many cases. Every data case is described as followed: In the first line there are three integers L, N, M, in the second line there are L integers represent the sequence A, in the third line there are N integers represent the sequences B, in the forth line there are M integers represent the sequence C. In the fifth line there is an integer S represents there are S integers X to be calculated. 1<=L, N, M<=500, 1<=S<=1000. all the integers are 32-integers. 

Output

For each case, firstly you have to print the case number as the form "Case d:", then for the S queries, you calculate if the formula can be satisfied or not. If satisfied, you print "YES", otherwise print "NO". 

Sample Input

3 3 3
1 2 3
1 2 3
1 2 3
3
1
4
10

Sample Output

Case 1:
NO
YES
NO 


思路:枚举三个数组,时间复杂度O(N^3),肯定会超时。所以可以把前两个数组的和先枚举出来,存在数组sum[260000]中,

由于要找是否存在sum[i] + c[j] = X, 可以把问题转换为在sum数组中查找是否有X-c[j]这个数。用二分查找sum数组即可。时间复杂度为: S * c数组的大小 * log(sum数组的大小) 

注意:不能在c数组中二分查找是否有X-sum[i]这个数,因为其时间复杂度为: S * sum数组的大小 * log(c数组的大小),由于题目中sum数组大小最大为250000,c数组大小最大为500,S为1000,所以会超时 

 1 #include <iostream>
 2 #include <queue>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <string>
 6 #include <algorithm>
 7 
 8 
 9 using namespace std;
10 
11 int a[501], b[501], c[501];
12 int sum[260000];
13 int L, N, M, S, X;
14 int cnt = 1;
15 
16 int main()
17 {
18     while(scanf("%d %d %d", &L, &N, &M) != EOF)
19     {
20         for(int i = 0; i < L; ++i)
21             scanf("%d", &a[i]);
22         for(int i = 0; i < N; ++i)
23             scanf("%d", &b[i]);
24         for(int i = 0; i < M; ++i)
25             scanf("%d", &c[i]);
26             
27         int k = 0;
28         for(int i = 0; i < L; ++i)
29             for(int j = 0; j < N; ++j)
30                 sum[k++] = a[i] + b[j];
31         
32         sort(sum, sum+k);
33         scanf("%d", &S);
34         printf("Case %d:
", cnt++);
35         while(S--)
36         {
37             scanf("%d", &X);
38             
39             int flag = 0;
40             for(int i = 0; i < M; ++i)
41             {
42                 int target = X - c[i];
43                 int left = 0, right = k;
44                 
45                 while(left <= right)
46                 {
47                     int mid = (left + right) / 2;
48                     if(sum[mid] == target)
49                     {
50                         flag = 1;
51                         break;
52                     }
53                     else if(sum[mid] < target)
54                         left = mid + 1;
55                     else
56                         right = mid - 1;
57                 }
58                 if(flag == 1)
59                 {
60                     printf("YES
");
61                     break;
62                 }
63             }
64             if(flag == 0)
65                 printf("NO
");
66             
67         }
68     }
69     
70 
71     
72     return 0;
73 }
原文地址:https://www.cnblogs.com/FengZeng666/p/11302734.html