注解
1、暴力解法:三重循环,TLE。
2、两重循环,第三个数采用二分搜索:仍然TLE。
3、把前2个数的和存在一个数组里,排序,然后遍历第三个数,对前2个数进行二分搜索:AC。
4、二分搜索可以采用STL中的版本,也可以手写。语言可以用C++,也可以用Java。都可以顺利AC。若采用Java,要采用快速输入节省时间。
代码
1、C++ STL二分搜索版本:
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int L, N, M;
int cas = 1;
while(scanf("%d %d %d", &L, &N, &M)>0) {
printf("Case %d:\n", cas++);
int A[L];
int B[N];
int C[M];
for(int i=0; i<L; i++) {
scanf("%d", &A[i]);
}
for(int i=0; i<N; i++) {
scanf("%d", &B[i]);
}
for(int i=0; i<M; i++) {
scanf("%d", &C[i]);
}
//对前2个数遍历,求和后放在一个数组中,排序(方便后面进行二分搜索)。
int ABsum[L*N];
int pos = 0;
for(int i=0; i<L; i++) {
for(int j=0; j<N; j++) {
ABsum[pos++] = A[i]+B[j];
}
}
sort(ABsum, ABsum+L*N);
int q;
scanf("%d", &q);
for(int i=0; i<q; i++) {
bool flag = false;
int num;
scanf("%d", &num);
//对C遍历,在ABsum中查找是否存在num-C[j]
for(int j=0; j<M; j++) {
if(binary_search(ABsum, ABsum+L*N, num-C[j])) {
flag = true;
printf("YES\n");
break;
}
}
if(!flag) {
printf("NO\n");
}
}
}
return 0;
}
2、C++,手写二分搜索版本:
#include <iostream>
#include <algorithm>
using namespace std;
//循环写法,只需要传数组名、数组长度、要查找的数字。
//如果采用递归写法,还要加上start,end坐标。
int binarySearch(int a[], int len, int num) {
int left = 0;
int right = len-1;
//这个地方一定是小于等于
//下面的left,right,分别是mid+1和mid-1
while(left<=right) {
int mid = (left+right)/2;
if(a[mid]==num) {
return mid;
} else if(a[mid]<num) {
left = mid+1;
} else {
right = mid-1;
}
}
return -1;
}
int main() {
int L, N, M;
int cas = 1;
while(scanf("%d %d %d", &L, &N, &M)>0) {
printf("Case %d:\n", cas++);
int A[L];
int B[N];
int C[M];
for(int i=0; i<L; i++) {
scanf("%d", &A[i]);
}
for(int i=0; i<N; i++) {
scanf("%d", &B[i]);
}
for(int i=0; i<M; i++) {
scanf("%d", &C[i]);
}
int ABsum[L*N];
int pos = 0;
for(int i=0; i<L; i++) {
for(int j=0; j<N; j++) {
ABsum[pos++] = A[i]+B[j];
}
}
sort(ABsum, ABsum+L*N);
int q;
scanf("%d", &q);
for(int i=0; i<q; i++) {
bool flag = false;
int num;
scanf("%d", &num);
for(int j=0; j<M; j++) {
int index = binarySearch(ABsum, L*N, num-C[j]);
if(index>=0) {
flag = true;
printf("YES\n");
break;
}
}
if(!flag) {
printf("NO\n");
}
}
}
return 0;
}
3、Java,手写二分搜索,快速输入:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Main {
public static int binarySearch(int[] a, int num) {
int left = 0;
int right = a.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (a[mid] == num) {
return mid;
} else if (a[mid] < num) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
public static void main(String[] args) throws IOException {
StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
int count = 1;
//读到输入结束
while (sc.nextToken() != sc.TT_EOF) {
System.out.println("Case " + count + ":");
count++;
int L = (int) sc.nval;
sc.nextToken();
int N = (int) sc.nval;
sc.nextToken();
int M = (int) sc.nval;
int[] A = new int[L];
int[] B = new int[N];
int[] C = new int[M];
for (int i = 0; i < L; i++) {
sc.nextToken();
A[i] = (int) sc.nval;
}
for (int i = 0; i < N; i++) {
sc.nextToken();
B[i] = (int) sc.nval;
}
for (int i = 0; i < M; i++) {
sc.nextToken();
C[i] = (int) sc.nval;
}
int[] ABsum = new int[L * N];
int tmp = 0;
for (int i = 0; i < L; i++) {
for (int j = 0; j < N; j++) {
ABsum[tmp++] = A[i] + B[j];
}
}
Arrays.sort(ABsum);
sc.nextToken();
int S = (int) sc.nval;
int[] q = new int[S];
for (int i = 0; i < S; i++) {
sc.nextToken();
q[i] = (int) sc.nval;
}
for (int query = 0; query < S; query++) {
boolean flag = false;
for (int i = 0; i < M; i++) {
if (binarySearch(ABsum, q[query] - C[i]) >= 0) {
flag = true;
System.out.println("YES");
break;
}
}
if (!flag) {
System.out.println("NO");
}
}
}
}
}