Live2D

POJ - 2785 4 Values whose Sum is 0 二分


4 Values whose Sum is 0
Time Limit: 15000MS Memory Limit: 228000K
Total Submissions: 25615 Accepted: 7697
Case Time Limit: 5000MS

Description

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

Input

The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 228 ) that belong respectively to A, B, C and D .

Output

For each input file, your program has to write the number quadruplets whose sum is zero.

Sample Input

6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45

Sample Output

5

Hint

Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

Source


题目大意:给4列数,每列有n个数字,从每列中取一个数,求四个数相加为零的情况有多少种。
思路:用两个数组,分别记录左边两列和右边两列的数相加的和,再将其中一个数组从小到大排列,将另一数组遍历一边,用二分的方法判断个数。
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[4005][4], sum1[16000001], sum2[16000001];
int main()
{
	int n, mid;
	
	while (~scanf("%d", &n))
	{
		int k = 0;
		for (int i = 0; i < n; i++)
		{
			scanf("%d %d %d %d", &a[i][0], &a[i][1], &a[i][2], &a[i][3]);
		}
		for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
		{
			sum1[k] = a[i][0] + a[j][1];
			sum2[k++] = a[i][2] + a[j][3];
		}
		sort(sum1, sum1 + k);

		int num = 0;
		for (int i = 0; i < k; i++)
		{
			int left = 0, right = k - 1;
			while (left <= right)
			{
				mid = (left + right) / 2;
				if (sum2[i] + sum1[mid] == 0)
				{
					num++;
					for (int j = mid + 1; j < k; j++)
					{
						if (sum2[i] + sum1[j] == 0)
							num++;
						else
							break;
					}
					for (int j = mid - 1; j >= 0; j--)
					{
						if (sum2[i] + sum1[j] == 0)
							num++;
						else
							break;
					}
					break;
				}
				if (sum2[i] + sum1[mid] > 0)
					right = mid - 1;
				else
					left = mid + 1;
			}
		}
		printf("%d\n", num);
	}
	return 0;
}



posted @ 2018-03-19 18:33  ITryagain  阅读(101)  评论(0编辑  收藏  举报