题目:
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 2
28 ) 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).
分析:
在a,b,c,d四组中分别找出四个数相加,找出相加为0的个数
简单的用回溯会超时,可以先把这四组变成两组,再用二分
代码:
#include
<iostream>
#include <iomanip>
#include <algorithm>
#include <stdio.h>
using namespace std ;
long long int a [ 4005 ],b [ 4005 ],c [ 4005 ],d [ 4005 ],h [ 16000005 ],f [ 16000005 ];
int sum = 0 ,n ;
void vp ( int k )
{
int l ,mid ,r ,x1 ,x2 ;
long long int x ;
l = 0 ;
r =n *n -1 ;
x =- 1 *h [k ];
while (l <=r )
{
mid =(l +r )/ 2 ;
if (f [mid ]<x )
l =mid +1 ;
else
if (f [mid ]>x )
r =mid -1 ;
else
{ x1 =x2 =mid ;
while (f [x1 ]==x &&x1 >= 0 )
{
sum ++;
x1 --;
}
while (f [x2 +1 ]==x &&x2 +1 <n *n )
{
sum ++;
x2 ++;
}
r =l -1 ;
}
}
}
int main ()
{
int i ,k ,j ;
scanf ( "%d" ,&n );
for (i = 0 ;i <n ;i ++)
scanf ( "%lld%lld%lld%lld" ,&a [i ],&b [i ],&c [i ],&d [i ]);
for (i = 0 ;i <n ;i ++)
for (j = 0 ;j <n ;j ++)
h [i *n +j ]=a [i ]+b [j ];
for (i = 0 ;i <n ;i ++)
for (j = 0 ;j <n ;j ++)
f [i *n +j ]=c [i ]+d [j ];
sort (h ,h +n *n );
sort (f ,f +n *n );
for (i = 0 ;i <n *n ;i ++)
vp (i );
printf ( "%d \n " ,sum );
}
#include <iomanip>
#include <algorithm>
#include <stdio.h>
using namespace std ;
long long int a [ 4005 ],b [ 4005 ],c [ 4005 ],d [ 4005 ],h [ 16000005 ],f [ 16000005 ];
int sum = 0 ,n ;
void vp ( int k )
{
int l ,mid ,r ,x1 ,x2 ;
long long int x ;
l = 0 ;
r =n *n -1 ;
x =- 1 *h [k ];
while (l <=r )
{
mid =(l +r )/ 2 ;
if (f [mid ]<x )
l =mid +1 ;
else
if (f [mid ]>x )
r =mid -1 ;
else
{ x1 =x2 =mid ;
while (f [x1 ]==x &&x1 >= 0 )
{
sum ++;
x1 --;
}
while (f [x2 +1 ]==x &&x2 +1 <n *n )
{
sum ++;
x2 ++;
}
r =l -1 ;
}
}
}
int main ()
{
int i ,k ,j ;
scanf ( "%d" ,&n );
for (i = 0 ;i <n ;i ++)
scanf ( "%lld%lld%lld%lld" ,&a [i ],&b [i ],&c [i ],&d [i ]);
for (i = 0 ;i <n ;i ++)
for (j = 0 ;j <n ;j ++)
h [i *n +j ]=a [i ]+b [j ];
for (i = 0 ;i <n ;i ++)
for (j = 0 ;j <n ;j ++)
f [i *n +j ]=c [i ]+d [j ];
sort (h ,h +n *n );
sort (f ,f +n *n );
for (i = 0 ;i <n *n ;i ++)
vp (i );
printf ( "%d \n " ,sum );
}