集训第四周(高效算法设计)J题 (中途相遇法)

Description

Download as PDF
 

The SUM problem can be formulated as follows: given four lists ABCD<tex2html_verbatim_mark> of integer values, compute how many quadruplet (abcd ) $ \in$AxBxCxD<tex2html_verbatim_mark> are such that a + b + c + d = 0<tex2html_verbatim_mark> . In the following, we assume that all lists have the same size n<tex2html_verbatim_mark> .

 

Input 

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

 

 


The first line of the input file contains the size of the lists n<tex2html_verbatim_mark> (this value can be as large as 4000). We then have n<tex2html_verbatim_mark> lines containing four integer values (with absolute value as large as 228<tex2html_verbatim_mark> ) that belong respectively to ABC<tex2html_verbatim_mark> and D<tex2html_verbatim_mark> .

 

Output 

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

 

 


For each input file, your program has to write the number quadruplets whose sum is zero.

 

Sample Input 

 

1

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

 

 


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).

 

如果按照原始方法,进行四重循环,毫无疑问是会超时的,只能使用方法把四重循环变成两重,可是每一个数最大可达2的28次方,使用short开数组也是行不通的,做一个大整数的hash。。不会,只能使用数组保存值,之后再进行查找了。。。

#include"iostream"
#include"cstring"
#include"algorithm"
#include"map"
#include"cmath"
using namespace std;
const int maxn=4000+10;
int book[16000010];
int a[maxn],b[maxn],c[maxn],d[maxn];
int main()
{
   int T;
   cin>>T;
while(T--)
  {
   int n;
   cin>>n;
   memset(book,0,sizeof(book));
   for(int i=0;i<n;i++)
   cin>>a[i]>>b[i]>>c[i]>>d[i];

   int f=0;
   for(int ia=0;ia<n;ia++)
    for(int ib=0;ib<n;ib++)
   {
       book[f++]=-(a[ia]+b[ib]);
   }
  int sum=0;
  sort(book,book+f);
  for(int ic=0;ic<n;ic++)
  for(int id=0;id<n;id++)
  {
      int temp=c[ic]+d[id];
      int x1=lower_bound(book,book+f,temp)-book;
      int x2=upper_bound(book,book+f,temp)-book;
      sum+=x2-x1;
  }
   cout<<sum<<endl;
   if(T) cout<<endl;
  }
    return 0;
}

 

posted @ 2015-08-05 17:06  江南何采莲  阅读(240)  评论(0编辑  收藏  举报