二分贪心 D

来源:互联网 发布:流行网络用语文言文 编辑:程序博客网 时间:2024/05/29 08:50

Description

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


         这道题的题意为给你n行,每行4个数,要求你从这四列中每列选一个数使他们的和为0,求种类数目。

      这道题普通的枚举绝对会超时,所以要用二分查找,并且先将前两列跟后两列分别求和,然后就转化为两个数组中找两个数使其他们的和为0的种类数了。


源代码如下:

#include<iostream>
#include<iomanip>
#include<algorithm>
#include<stdio.h>
int m,a[4005][4],x[16000005]={0},y[16000005]={0};
using namespace std;
int main()
{ int max,min,mid,n,i,j,k=0,h=0;
  
  scanf("%d",&n);
  for(i=0;i<n;++i)
   for(j=0;j<4;++j)
    { scanf("%d",&a[i][j]);
    }
  for(i=0;i<n;++i)
    for(j=0;j<n;++j)
    { x[k]=a[i][0]+a[j][1];
      y[k]=a[i][2]+a[j][3];
      ++k;
}
  sort(x,x+k);
  sort(y,y+k);
  for(i=0;i<k;++i)
  { 
    min=0;
    max=k-1;
    while(min<=max)
    { mid=(min+max)/2;
      if(y[mid]+x[i]==0)
      { h++;
        for(j=mid+1;j<k;++j)
        { if(y[j]+x[i]==0)h++;
          else break;
}
for(j=mid-1;j>=0;--j)
        { if(y[j]+x[i]==0)h++;
          else break;
}
        break;
 }
      if(y[mid]+x[i]<0)
      min=mid+1;
   else max=mid-1;
}
  }
  printf("%d\n",h);
}


        注意这种较大循环的输入输出要用scanf跟printf,用cin跟cout容易超时。



0 0
原创粉丝点击