Title Description
ZJM has four columns A, B, C, D, each column has the number of digits n. ZJM a number taken from each respective column number, he would like to know how many kinds of programs such that the number of 4 and 0.
When a number of columns has the same plurality of numbers, to treat them as a different number.
Please help him!
Input format
The first line: n (number representative of the number of columns) (1≤n≤4000)
The next n-th row, the i-th row of four numbers, each number of columns A, B, C, D in the i-th digit (digit 2 to the power of not more than 28)
Output format
output number of different combinations.
Input Example
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 Example
5
Sample interpretation
Digital intended to meet the problem of: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46), (- 32 and 30 - 75, 77), (-32, -54, 56, 30).
Problem-solving ideas
apparently directly through each series, it will be a staggering complexity of O (N ^ 4). Turtle, Floyd algorithm watched want to cry.
So this question Zezheng it?
The answer is a dichotomy.
For the A + B + C + D = 0, we can make the appropriate modifications:
So we can get the relation: A + B = - (C + D)
So we only need to look at a separate A + B and C + D on it, all of a sudden opened a complexity of the root it!
After due dichotomy requires strict monotone sequence, so we finished the input, pre-processing at an array of A + B: Let them in ascending order.
Note that, where an array of A + B refers to the number A of all the respective numbers of B plus all, if a total of n array, then the size of the A + B of the array should be n ^ 2.
Then, for each of C + D, we give him a trans and binary search, and the current c + "first occurrence of" the same size and the value of d "appears in the last array of A + B local". This is because the title may be the same when it comes to the numbers, to be as different numbers to look at, ie many-count.
So we can get the code:
#include <iostream>
#include <algorithm>
#include <vector>
#include <algorithm>
using namespace std;
vector<int>ab;
vector<int>l[4];
int n;
bool LTOM(int a, int b)//升序排列函数
{
return a < b;
}
int Front(int value)//找到第一个值
{
int l = 0, r = n * n - 1, ans = -1;
while (l <= r)
{
int mid = (l + r) >> 1;
if (ab[mid] == value)
{
ans = mid;
r = mid - 1;
}
else if (ab[mid] > value) r = mid - 1;
else
l = mid + 1;
}
return ans;
}
int Last(int value)//找到最后一个值
{
int l = 0, r = n * n - 1, ans = -1;
while (l <= r)
{
int mid = (l + r) >> 1;
if (ab[mid] == value)
{
ans = mid;
l = mid + 1;
}
else if (ab[mid] > value) r = mid - 1;
else l = mid + 1;
}
return ans;
}
int main()
{
cin >> n;
int temp;
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= 3; j++)
{
cin >> temp;
l[j].push_back(temp);
}
}
for(int i=0;i<n;i++)
for (int j = 0; j < n; j++)
{
ab.push_back(l[0][i] + l[1][j]);
//cd.push_back(-(l[2][i] + l[3][j]));
}
sort(ab.begin(), ab.end(), LTOM);//使ab升序
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
int cd = -(l[2][i] + l[3][j]);
int f = Front(cd);
if (f == -1) continue;
else
ans += (Last(cd) - f + 1);
}
cout << ans << endl;
}