Can you find it?
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/10000 K (Java/Others)
Total Submission(s): 16926 Accepted Submission(s): 4305
Problem 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
题意就不说了吧。。。
思路:把两个数组压缩成一个新数组T,枚举另外一个数组元素Y。对于要验证的结果X:则问题就变成了在数组T里面查找是否存在元素X - Y。
AC代码:561ms 在压缩新数组的时候,可以标记下某个元素是否存在,若存在不再进数组。在遍历另外一个数组元素时也可以标记下,这样应该能稍稍优化下吧。有兴趣的可以写下。
注意后面两个代码是错误的!!!
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 500+1
using namespace std;
int a[MAXN], b[MAXN], c[MAXN];
int d[250000+100];
int main()
{
int L, N, M, S, X;
int k = 1;
int top;
bool flag;
while(scanf("%d%d%d", &L, &N, &M) != EOF)
{
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]);
//sort(a, a+L);
//sort(b, b+N);
top = 0;
for(int i = 0; i < L; i++)
{
for(int j = 0; j < N; j++)
d[top++] = a[i] + b[j];
}
sort(d, d+top);
scanf("%d", &S);
printf("Case %d:\n", k++);
while(S--)
{
scanf("%d", &X);
flag = false;
for(int i = 0; i < M; i++)
{
int ans = X - c[i];//我们要搜索的结果
int left = 0, right = top - 1, mid;
while(right >= left)
{
mid = (left + right) >> 1;
if(d[mid] == ans)
{
flag = true;
break;
}
else if(d[mid] > ans) right = mid - 1;
else left = mid + 1;
}
if(flag)
break;
}
if(!flag)
printf("NO\n");
else
printf("YES\n");
}
}
return 0;
}
错误代码一:
用set存储新数组元素一直MLE,无语。。。。
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
#define MAXN 500+1
using namespace std;
int a[MAXN], b[MAXN], c[MAXN];
int main()
{
int L, N, M, S, X;
int k = 1;
int top;
bool flag;
while(scanf("%d%d%d", &L, &N, &M) != EOF)
{
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]);
set<int> d;
for(int i = 0; i < L; i++)
{
for(int j = 0; j < N; j++)
d.insert(a[i] + b[j]);
}
scanf("%d", &S);
printf("Case %d:\n", k++);
while(S--)
{
scanf("%d", &X);
flag = false;
for(int i = 0; i < M; i++)
{
int ans = X - c[i];//我们要搜索的结果
set<int>::iterator pos;
pos = d.find(ans);
if(pos != d.end())
{
flag = true;
break;
}
}
if(!flag)
printf("NO\n");
else
printf("YES\n");
}
}
return 0;
}
代码二:用set存储另外一个数组,结果TLE。。。
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
#define MAXN 500+1
using namespace std;
int a[MAXN], b[MAXN], c[MAXN];
int e[2500000+10];
set<int> d;
int main()
{
int L, N, M, S, X;
int k = 1;
int top;
bool flag;
while(scanf("%d%d%d", &L, &N, &M) != EOF)
{
d.clear();
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]), d.insert(c[i]);
top = 0;
for(int i = 0; i < L; i++)
{
for(int j = 0; j < N; j++)
e[top++] = a[i] + b[j];
}
scanf("%d", &S);
printf("Case %d:\n", k++);
while(S--)
{
scanf("%d", &X);
flag = false;
for(int i = 0; i < top; i++)
{
int ans = X - e[i];//我们要搜索的结果
set<int>::iterator pos;
pos = d.find(ans);
if(pos != d.end())
{
flag = true;
break;
}
}
if(!flag)
printf("NO\n");
else
printf("YES\n");
}
}
return 0;
}