Four columns: determination of the four columns taken out and the number of kinds of programs for the total number 0. c ++

Four columns

There are four columns A, B, C, D, each column has the number of digits n. A number taken from each respective column number, to ask how many such programs and number 4 is 0.
When a number of columns has the same plurality of numbers, to treat them as a different number.

Input of the first row: n (number representative of the number of columns) (1≤n≤4000)
the next n-th row, the i-th row of four numbers, each represents the number of columns A, B, C, D of i digits (digit 2 to the power of not more than 28)
the number of output of different combinations

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

(Answer: (- 45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46), (--32, 30, -75, 77) , (-32, -54, 56, 30)

Ideas:

  • A first reaction force, can be calculated from all results quartet cycle, equal to 0 +. But such is the complexity of the n- 4 , will certainly be explosive.
  • Therefore, attempts to use binary thought, can enumerate A + B and C + D, respectively, the results for each of C + D, to find out whether it has the opposite of the A + B.
  • If direct violence to find in the A + B in the case, the complexity and not much lower, it can first answer to A + B are sorted, and then continue to use the binary idea to find, lock opposite number positions (use a binary search first number and location opposite a position opposite to the last number, the position of the last - in a first position opposite to the + 1 = the number of times of appearance)
#include<algorithm>
#include<cmath> 
#include<vector>
#include<iostream>
using namespace std;
int a[1000001];
int b[1000001];
int c[1000001];
int d[1000001];
vector<int>ab;
int findbegin(int x)
{
	int l=0,r=ab.size()-1,ans=-1;
	while(l<=r)
	{
		int m=(l+r)/2;
		if(ab[m]==x)
		{
			ans=m;
			r=m-1;
		}
		else if(ab[m]>x)	r=m-1;
		else l=m+1;
	}
	return ans;
}
int findend(int x)
{
	int l=0,r=ab.size()-1,ans=-1;
	while(l<=r)
	{
		int m=(l+r)/2;
		if(ab[m]==x)
		{
			ans=m;
			l=m+1;
		}
		else if(ab[m]>x)	r=m-1;
		else l=m+1;
	}
	return ans;
}
int main()
{
	int n;
	cin>>n;
	int ans=0;
	for(int i=0;i<n;i++)
	{
		
		cin>>a[i]>>b[i]>>c[i]>>d[i];
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			ab.push_back(a[i]+b[j]);
		}
	}
	sort(ab.begin(),ab.end());
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			int temp=(c[i]+d[j])*(-1);//枚举c+d,若互为相反数则确定是一组 
			int l=findbegin(temp);
			int r=findend(temp);
			if(l!=-1) ans+=(r-l+1);
		}
	}
	cout<<ans<<endl;
	return 0;
}
Published 29 original articles · won praise 1 · views 943

Guess you like

Origin blog.csdn.net/qq_44654498/article/details/104926493