zoukankan      html  css  js  c++  java
  • poj2785(折半枚举)

    给定A,B,C,D四个集合,每个集合有n个数,一个元组t={a,b,c,d},其中a,b,c,d分别属于ABCD,且a+b+c+d=0

    求这样的元组有多少个

    1<=n<=4000

    |ai,bi,ci,di|<2^28

    分析:

    暴力枚举n^4显然行不通,n^3也不可

    我们可以先n^2计算出a+b的所有值,然后对于每个c+d,寻找-(c+d)=a+b

    至于查找过程,把{a+b}进行排序然后二分查找

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<string>
     5 #include<queue>
     6 #include<vector>
     7 #include<set>
     8 #include<map>
     9 #include<cmath>
    10 #include<algorithm>
    11 
    12 #define ll long long 
    13 #define mem(a,b) memset(a,b,sizeof(a))
    14 
    15 using namespace std;
    16 const int maxn=4004;
    17 int sum[maxn*maxn];
    18 int A[maxn],B[maxn],C[maxn],D[maxn];
    19 int cnt=0;
    20 int main()
    21 {
    22     //freopen("in.in","r",stdin);
    23     int n;
    24     cin>>n;
    25     for(int i=1;i<=n;i++)
    26     {
    27         scanf("%d%d%d%d",&A[i],&B[i],&C[i],&D[i]);
    28     }
    29     for(int i=1;i<=n;i++)
    30     {
    31         for(int j=1;j<=n;j++)
    32         {
    33             sum[cnt++]=A[i]+B[j];
    34         }
    35     }
    36     sort(sum,sum+cnt);
    37     ll res=0;
    38     for(int i=1;i<=n;i++)
    39     {
    40         for(int j=1;j<=n;j++)
    41         {
    42             int t=-(C[i]+D[j]);
    43             int l=upper_bound(sum,sum+cnt,t)-lower_bound(sum,sum+cnt,t);
    44             res+=l;
    45         }
    46     }
    47     printf("%ld
    ", res);
    48 }

    注意:对于每一个c+d,可能不止有一个a+b=-(c+d),要把所有满足条件的a+b都举出来,所以是

    int l=upper_bound(sum,sum+cnt,t)-lower_bound(sum,sum+cnt,t);
    res+=l;

    学到了什么:

      lower_bound是返回大于等于待查找元素的第一个值的位置

      upper_bound是返回大于待查找元素的第一个值的位置(之前一直以为二者是相对的,upper_bound返回的是小于等于待查找元素的第一个位置)

      

  • 相关阅读:
    linux 下共享内存
    linux shmget shmctl
    linux 进程优先级 之设置实时进程 (另一种方式是设置nice值)
    linux .so .a .o 文件
    linux 时间模块 三
    linux 时间模块 二
    linux 时间模块 一
    设计模式之原型模式(php实现)
    设计模式之建造者模式(php实现)
    设计模式之单例模式(php实现)
  • 原文地址:https://www.cnblogs.com/codeoosacm/p/10262650.html
Copyright © 2011-2022 走看看