Trouble
Time Limit: 10000/5000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 3856 accepted submission (s): 1223
Problem descriptionhassan 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?
Inputfirst 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.
Outputfor 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
221 -11 -11 -11 -11 -131 2 3-1 -2 -34 5 6-1 3 2-4 -10 -1
Sample output
NoYes
Source2012 multi-university training contest 4
Recommendzhoujiaqi2010
Question:
Given five sets, five numbers are extracted from the five sets. If A1 + A2 + A3 + A4 + A5 = 0, yes is output; otherwise, no is output; the value of the set size less than 200 AI is [-10 ^ 15, 1 0 ^ 15].
Ideas:
Merge the first 1, 2 numbers (and save them into the array) to up []. Merge 3 or 4 rows into down []. Then sort the two arrays. Then enumerate the number of the last row. Maintain two pointers L and R for each number in the last row. Start to point to the rightmost end of up and the leftmost end of down respectively.
Then move the pointer according to temp = up [R] + down [l] + A [I. If temp> 0, r --. Temp <0. L ++. Temp = 0. The answer is found. Directly jump out. Why can l and R change directly?
It only utilizes the greedy idea. If temp> 0. The value of up [R] is greater than that of up [R. Because the values after down [l] are greater than down [l. Up [R] and they must be larger. The same is true for temp <0.
This method is highly efficient. Unfortunately, I did not expect it. There are still many things to learn .....
Code:
# Include <stdio. h> # include <string. h >#include <iostream >#include <algorithm> using namespace STD ;__ int64 num [5] [210]; // _ int64. _ int64 up [40010], down [40010], temp; // temp is _ int64 .. It was pitted again .. Int main () {int I, j, t, n, l, R, flag, CNT, PTR; scanf ("% d", & T); While (t --) {scanf ("% d", & N); flag = 0; CNT = PTR = 0; for (I = 0; I <5; I ++) for (j = 0; j <n; j ++) scanf ("% i64d", & num [I] [J]); for (I = 0; I <n; I ++) for (j = 0; j <n; j ++) up [CNT ++] = num [0] [I] + num [1] [J]; // Save the sum of the first two layers and for (I = 0; I <N; I ++) for (j = 0; j <n; j ++) down [PTR ++] = num [2] [I] + num [3] [J]; // sum (Up, Up + CNT) of the last two layers ); sort (Down, Down + PTR); for (I = 0; I <n; I ++) {r = cnt-1; L = 0; while (L <PTR & R> = 0) // greedy thoughts reduce the number of comparisons {temp = up [R] + down [l] + num [4] [I]; if (temp> 0) r --; else if (temp = 0) {flag = 1; break;} else l ++;} If (FLAG) break ;} if (FLAG) printf ("Yes \ n"); else printf ("NO \ n");} return 0 ;}