ACM-二分贪心D-04

来源:互联网 发布:安全数据库 编辑:程序博客网 时间:2024/06/05 09:09

(欢迎阅读我的博客,如发现错误或有建议请评论留言,谢谢。) 

题目如下:

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).
题目思路:

就是在每一列中找一个数,使得四个数的和为0,求出一共有几种情况,这个题的话若直接考虑四列使用二分的话,控制条件是不好写的,但是不难发现如果我们先把四列变为两列,将第一列的每一个数和第二列的每一个数相加得到n^2个数,后两列同样得到n^2个数,对于新得到的两列把后一列取倒数,那么只要两数相等就满足题意。因为一列数中有可能有相等的数,所以当我们二分到满足条件的数时还需要对上下的数进行判断,直到上下的数不满足条件为止。

代码如下:

#include<stdio.h>#include<algorithm>using namespace std;long a[4000],b[4000],c[4000],d[4000],w[16000000],v[16000000];int main(){int n,i,j,k=0,high,low,sum=0,mid,s=0;scanf("%d",&n);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++){w[k]=a[i]+b[j];k++;}k=0;for(i=0;i<n;i++)for(j=0;j<n;j++){v[k]=c[i]+d[j];v[k]=-v[k];k++;}sort(w,w+k);sort(v,v+k);for(i=0;i<k;i++){high=k-1;low=0;while(low<=high){s++;mid=(high+low)/2;if(v[mid]==w[i]){sum++;for(j=mid+1;j<k;j++)       /*{if(v[j]==w[i])sum++;                else break;}                           对上下的数进行判断for(j=mid-1;j>=0;j--)     {if(v[j]==w[i])sum++;else break;        */}break;}if(v[mid]<w[i])low=mid+1;if(v[mid]>w[i])high=mid-1;}}printf("%d\n",sum);}

0 0