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;
}