Week4 B four series

Title description:

ZJM has four series A, B, C, D, each series has n numbers. ZJM takes a number from each sequence, and he wants to know how many schemes make the sum of the four numbers zero.
When there are multiple identical numbers in a sequence, treat them as different numbers.

Input format:

The first row: n (representing the number of numbers in the sequence) (1≤n≤4000) In the
next n rows, the i-th row has four numbers, which represent the i-th in the sequence A, B, C, D Digits (numbers not more than 2 to the 28th power)

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

Output format:

The number of different combinations is output.

Sample Output:

5

Ideas:

If you enumerate the data one by one, you will reach the nth power of four, and the time complexity is too high. Therefore, we first use the first two arrays to enumerate, record their sum in the sum array, then enumerate the sum of the last two arrays, and then look for their opposite number in the sum array. When looking for the number of opposite numbers, we choose to sort the sum array, and then divide by two to find the first and last position of the opposite number, so as to find the number of opposite numbers. This can reduce the time complexity.

Code:

#include <iostream>
#include <algorithm>

using namespace std;

int findmax(int x,int n,int *a)
{
	int l = 0, r = n - 1, ans = -1;
	while (l <= r)
	{
		int mid = (l + r) >> 1;
		if (a[mid] == x)
		{
			ans = mid;
			l = mid + 1;
		}
		else if (a[mid] > x)r = mid - 1;
		else l = mid + 1;
	}
	return ans;
}

int findmin(int x, int n, int *a)
{
	int l = 0, r = n - 1, ans = -1;
	while (l <= r)
	{
		int mid = (l + r) >> 1;
		if (a[mid] == x)
		{
			ans = mid;
			r = mid - 1;
		}
		else if (a[mid] > x)r = mid - 1;
		else l = mid + 1;
	}
	return ans;
}

int main()
{
	int n;
	while (scanf("%d",&n)!=EOF)
	{
		int count = 0;
		int *a = new int[n];
		int *b = new int[n];
		int *c = new int[n];
		int *d = new int[n];
		for (int i = 0; i < n; i++)
			cin >> a[i] >> b[i] >> c[i] >> d[i];
		int *sum = new int[n*n]();
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				sum[i*n + j] = a[i] + b[j];
		sort(sum, sum + n * n);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
			{
				int last = -1;
				int tp = -(c[i] + d[j]);
				int max = findmax(tp, n*n, sum);
				int min = findmin(tp, n*n, sum);
				int ans = max - min + 1;
				if (min != last && max != last)
					count += ans;
			}
		cout << count << endl;
	}
	return 0;
}

Published 32 original articles · praised 0 · visits 689

Guess you like

Origin blog.csdn.net/qq_43814559/article/details/104978775