HDU

来源:互联网 发布:天谕白帝捏脸数据 编辑:程序博客网 时间:2024/06/12 01:34

Trouble

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6158 Accepted Submission(s): 1721

Problem Description

Hassan is in trouble. His mathematics teacher has given him a very difficult problem called 5-sum. Please help him.
The 5-sum problem is defined as follows: Given 5 sets S_1,…,S_5 of n integer numbers each, is there a_1 in S_1,…,a_5 in S_5 such that a_1+…+a_5=0?

Input

First line of input contains a single integer N (1≤N≤50). N test-cases follow. First line of each test-case contains a single integer n (1<=n<=200). 5 lines follow each containing n integer numbers in range [-10^15, 1 0^15]. I-th line denotes set S_i for 1<=i<=5.

Output

For each test-case output “Yes” (without quotes) if there are a_1 in S_1,…,a_5 in S_5 such that a_1+…+a_5=0, otherwise output “No”.

Sample Input

2
2
1 -1
1 -1
1 -1
1 -1
1 -1
3
1 2 3
-1 -2 -3
4 5 6
-1 3 2
-4 -10 -1

Sample Output

No
Yes

Source

2012 Multi-University Training Contest 4

Recommend

zhoujiaqi2010 | We have carefully selected several similar problems for you: 4331 4332 4333 4335 4336

题意:

给定5个集合,从5个集合中分别选出一个数使得和为0,问是否存在

如果是哈希来做,我们可以转化为两个集合的查询操作,那么我们可以先将5个集合分成两个或者三个集合,然后分别合并成两个新的集合,然后将其中一个丢进哈希表,另一个遍历去寻找即可

如果用贪心,可以把1,2两个集合合并以后排序,3,4两个集合合并以后排序,若现在第5个集合取的元素是x,问题转化成前两个集合能否找到两个元素记加起来为-x,
对于两个有序集合可以枚举其中一个,二分另一个,因为合并的集合大小本身是N*N,复杂度O(N^3logN)

然而有更优的贪心做法,利用两根指针,L在a最小值,R在b最大值,然后如果a[L]+a[R]>-x,那么–R,否则++L,可以再O(size(a)+size(b))内找到解去掉了logN
复杂度O(N^3)

另外至于范围是10^15,一开始忽略了1,看成了10^5,用了int WA了8发……

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int maxn=1e5+5,maxm=200+5;LL a[maxn],b[maxn],p1[maxm],p2[maxm],x;int cnt1,cnt2,n;int main(){  int T;  scanf("%d",&T);  while(T--)  {    scanf("%d",&n);    for(int i=1;i<=n;++i)scanf("%lld",p1+i);    for(int i=1;i<=n;++i)scanf("%lld",p2+i);    cnt1=0;    for(int i=1;i<=n;++i)      for(int j=1;j<=n;++j)        a[++cnt1]=p1[i]+p2[j];    sort(a+1,a+1+cnt1);    cnt1=unique(a+1,a+1+cnt1)-a-1;    for(int i=1;i<=n;++i)scanf("%lld",p1+i);    for(int i=1;i<=n;++i)scanf("%lld",p2+i);    cnt2=0;    for(int i=1;i<=n;++i)      for(int j=1;j<=n;++j)        b[++cnt2]=p1[i]+p2[j];    sort(b+1,b+1+cnt2);    cnt2=unique(b+1,b+1+cnt2)-b-1;    bool ans=1;    for(int i=1;i<=n;++i)    {      scanf("%lld",&x);       if(ans==0)continue;      int l=1,r=cnt2;      while(l<=cnt1&&r>0)      {        if(a[l]+b[r]>-x)--r;        else if(a[l]+b[r]<-x)++l;        if(a[l]+b[r]==-x){ans=0;break;}      }    }    if(ans==0)printf("Yes\n");    else printf("No\n");  }  return 0;}
原创粉丝点击