Trouble
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 874 Accepted Submission(s): 270
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?
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
小技巧:
给定两个有序集合X、Y分别有 x 和 y 个元素,在 X 中选择一个 a ,在 Y 中选择一个 b ,使得 a+b=c,c是给定的;可以在 O(x+y)时间内完成
题意:给你5个集合,每个集合都有 n 个元素,从这5个集合中每个集合选择一个元素,如果这5个元素和为 0 ,则输出Yes ,否则输出No。
分析:问题简化一下给定两个有序集合X、Y分别有 x 和 y 个元素,问在 X 中选择一个 a ,在 Y 中选择一个 b ,使得 a+b=c,c是给定的;
上面问题的可以再 O(x+y)时间内完成,定义两个指针 px 、py ;px 指向X中的第一个元素,py 指向Y中最后一个元素;
if X(px)+Y(py)==c return true
if X(px)+Y(py)<c px++
if X(px)+Y(py)>c py--
上面问题解决了,那么五个集合问题也就好办了,第一和第二个集合 合成一个新集合1,第三和第四集合 合成一个新集合2, n^2个元素,
依次枚举第五个集合中的元素,是否在新集合1 和 新集合2 中,时间复杂度为O(n^3);
心得:比赛时写的是O(n^3 log n^2)的程序,持续TLE
View Code
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #define MAXN 40010 6 #define MAXM 210 7 8 using namespace std; 9 10 long long sum1[MAXN],sum2[MAXN],num[5][MAXM]; 11 int cnt; 12 13 bool work(int n) 14 { 15 int p1,p2,k; 16 long long key; 17 for(k=0;k<n;k++) 18 { 19 key=-num[4][k]; 20 p1=0;p2=cnt-1; 21 while(p1<cnt&&p2>=0) 22 { 23 if(sum1[p1]+sum2[p2]==key) return true; 24 else if(sum1[p1]+sum2[p2]<key) p1++; 25 else p2--; 26 } 27 } 28 return false; 29 } 30 31 int main() 32 { 33 int test,i,j,n; 34 scanf("%d",&test); 35 while(test--) 36 { 37 scanf("%d",&n); 38 for(i=0;i<5;i++) for(j=0;j<n;j++) 39 { 40 scanf("%I64d",&num[i][j]); 41 } 42 cnt=0; 43 for(i=0;i<n;i++) for(j=0;j<n;j++) 44 { 45 sum1[cnt++]=num[0][i]+num[1][j]; 46 } 47 cnt=0; 48 for(i=0;i<n;i++) for(j=0;j<n;j++) 49 { 50 sum2[cnt++]=num[2][i]+num[3][j]; 51 } 52 sort(sum1,sum1+cnt); 53 sort(sum2,sum2+cnt); 54 if(work(n)) printf("Yes\n"); 55 else printf("No\n"); 56 } 57 return 0; 58 }