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:\n", 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\n"); 61 break; 62 } 63 } 64 if(flag == 0) 65 printf("NO\n"); 66 67 } 68 } 69 70 71 72 return 0; 73 }