博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj2785 简单二分
阅读量:4687 次
发布时间:2019-06-09

本文共 2118 字,大约阅读时间需要 7 分钟。

4 Values whose Sum is 0
Time Limit: 15000MS   Memory Limit: 228000K
Total Submissions: 19243   Accepted: 5744
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 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).
 
题目大意:四个数列,问你有几种可能的组合满足,a[i]+b[j]+c[k]+d[e]==0;
思路分析:直接遍历所有情况的话,复杂度是n^4。肯定超时,本题应该采用二分做,先进行数组合并,将四个数组合成为两个n*n的数组,然后对
其中一个排序,这样就可以用二分查找另一个数组是否存在对应的数,这样复杂度就变成了n*nlogn^2,这样就不会超时了。
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int inf=0xffffff;
const int maxn=4000+10;
int a[maxn],b[maxn],c[maxn],d[maxn];
int f1[maxn*maxn],f2[maxn*maxn];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int cut=0;
        for(int i=0;i<n;i++)
            scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                f1[i*n+j]=a[i]+b[j];
                f2[i*n+j]=c[i]+d[j];
            }
        }
        sort(f2,f2+n*n);
    for(int i=0;i<n*n;i++)
    {
        int low=0,high=n*n-1;
    while(low<=high)
    {
        int mid=(low+high)/2;
        if(f2[mid]==-f1[i])
        {
             cut++;
             for(int j=mid-1;j>=0;j--)
             {
                 if(f2[j]!=-f1[i]) break;
                 cut++;
             }
             for(int j=mid+1;j<n*n;j++)
             {
                  if(f2[j]!=-f1[i]) break;
                 cut++;
             }
             break;
        }
      else if(f2[mid]<-f1[i]) low=mid+1;
      else high=mid-1;
    }
    }
    cout<<cut<<endl;
    }
    return 0;
}

转载于:https://www.cnblogs.com/xuejianye/p/5485236.html

你可能感兴趣的文章
12/17面试题
查看>>
css 继承和层叠
查看>>
javascript实现图片轮播3D效果
查看>>
ssl初一组周六模拟赛【2018.3.17】
查看>>
[RxJS] Avoid mulit post requests by using shareReplay()
查看>>
C++和C#之间的数据类型对应关系
查看>>
模型分离(选做)
查看>>
LeetCode 242. Valid Anagram
查看>>
观察者模式------《Head First 设计模式》
查看>>
JSP表单提交乱码
查看>>
如何适应现代雇佣关系
查看>>
【BZOJ4592】[Shoi2015]脑洞治疗仪 线段树
查看>>
redis sentinel 读写分离
查看>>
团队项目(第五周)
查看>>
ElasticSearch6(三)-- Java API实现简单的增删改查
查看>>
选拔赛 I 点进来吧,这里有你想要的
查看>>
SQL 优化经验总结34条
查看>>
开源 视频会议 收藏
查看>>
核心J2EE模式 - 截取过滤器
查看>>
test1
查看>>