zoukankan      html  css  js  c++  java
  • POJ 2785:4 Values whose Sum is 0 二分

    4 Values whose Sum is 0
    Time Limit: 15000MS   Memory Limit: 228000K
    Total Submissions: 18221   Accepted: 5363
    Case 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 -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).

    题意是给出4列数,从每一列中挑选一个数字,问有多少种方法使这四个数的和为0。

    求出每两列的数的和,再二分查找。

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <map>
    #pragma warning(disable:4996)
    using namespace std;
    
    int a[4005],b[4005],c[4005],d[4005];
    int sum1[4005*4005],sum2[4005*4005];
    int n;
    
    int main()
    {	
    	//freopen("i.txt","r",stdin);
    	//freopen("o.txt","w",stdout);
    
    	int i,j;
    	
    	scanf("%d",&n);
    
    	for(i=1;i<=n;i++)
    	{
    		scanf("%d%d%d%d",a+i,b+i,c+i,d+i);
    	}
    
    	int num1=0;
    	for(i=1;i<=n;i++)
    	{
    		for(j=1;j<=n;j++)
    		{
    			sum1[++num1] = -(a[i]+b[j]);
    			sum2[num1] = (c[i]+d[j]);
    		}
    	}
    	sort(sum1+1,sum1+1+num1);
    	sort(sum2+1,sum2+1+num1);
    
    	int ans=0;
    	sum1[0]= -268435456*2 - 1;
    	sum1[num1+1] = 268435456*2 + 1;
    	for(i=1;i<=num1;i++)
    	{
    		int left = 0;
    		int right = num1+1;
    		int mid;
    		while(left<right)
    		{
    			mid=(left+right)/2;
    			if(sum2[i]<=sum1[mid])
    			{
    				right=mid;
    			}
    			else
    			{
    				left= mid+1;
    			}
    		}
    		while(sum2[i]==sum1[right]&&right<=num1)
    		{
    			ans++;
    			right++;
    		}
    	}
    
    	printf("%d
    ",ans);
    	//system("pause");
    	return 0;
    }
    




    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    BZOJ 3513: [MUTC2013]idiots(fft)
    BZOJ 2194: 快速傅立叶之二(fft)
    BZOJ 3779: 重组病毒(线段树+lct+树剖)
    LUOGU P3723 [AH2017/HNOI2017]礼物 (fft)
    CF 622F (拉格朗日插值)
    LUOGU P4781 【模板】拉格朗日插值
    bzoj 4184 shallot——线段树分治+线性基
    51nod 1673 树有几多愁——虚树+状压DP
    bzoj 3611(洛谷 4103) [Heoi2014]大工程——虚树
    bzoj 2286(洛谷 2495) [Sdoi2011]消耗战——虚树
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4899543.html
Copyright © 2011-2022 走看看