POJ2785

来源:互联网 发布:移动数据终端 市场 编辑:程序博客网 时间:2024/05/18 01:20
4 Values whose Sum is 0
Time Limit: 15000MS
Memory Limit: 228000KTotal Submissions: 19783
Accepted: 5909Case Time Limit: 5000MS

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


逐步缩小范围法是一种常见的思维方法。二分查找便是基于这种思路,它遵循分治思想:把原序列划分成元素个数尽量接近的两个子序列,然后递归查找。二分查找只适用于有序序列,时间复杂度为O(logn)


#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#define MAX 4005using namespace std;int ab[MAX*MAX], cd[MAX*MAX];int a[MAX], b[MAX], c[MAX], d[MAX];int bs(int *a, int key, int n);int main(){    int n,i,j,ans;    while (scanf("%d",&n)!=EOF)    {        for (i = 0; i < n; ++i)            scanf("%d%d%d%d",&a[i], &b[i], &c[i], &d[i]);        for (i = 0; i < n; i++)            for (j = 0; j < n; j++)        {            ab[i*n+j] = a[i] + b[j];            cd[i*n+j] = c[i] + d[j];           }           sort(ab,ab+n*n);           for(ans=i=0;i<n*n; i++)               ans+=bs(ab,-cd[i],n*n);           printf("%d\n", ans);    }    return 0;}int bs(int *a, int key, int n){    int cnt, hi, lo, mid, tmp;    cnt = 0;    hi = n-1;    lo = 0;    while (lo <= hi)    {        mid = (hi+lo) >> 1;        if (key==a[mid]) break;        if (key<a[mid]) hi=mid-1;        else lo=mid+1;    }    if (key==a[mid])    {        cnt++;        tmp=mid;        while (tmp>0&&key==a[--tmp]) cnt++;        while (mid<n-1&&key==a[++mid]) cnt++;    }    return cnt;}


0 0
原创粉丝点击