zoukankan      html  css  js  c++  java
  • poj 2785(折半枚举+二分搜索)

    传送门:Problem 2785

    题意:

      给定 n 行数,每行都有 4 个数A,B,C,D。

      要从每列中各抽取出一个数,问使四个数的和为0的所有方案数。

      相同数字不同位置当作不同数字对待。

    题解:

      如果采用暴力的话,从4个数列中选择数组合,共有(N^4)种选择,故时间复杂度为O(N^4),指定会超时。

      但,如果将它们分成 AB,CD两组,每组只有 N^2 个组合,而 N 的数据范围为 N < 4000,故采用此种方法不会超时。

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 #define ll long long
     6 const int maxn=4000+50;
     7 
     8 int n;
     9 int a[maxn*maxn];
    10 int b[maxn*maxn];
    11 int num[maxn][5];
    12 
    13 ll Solve()
    14 {
    15     int index=1;
    16     for(int i=1;i <= n;++i)
    17         for(int j=1;j <= n;++j)
    18         {
    19             a[index]=num[i][1]+num[j][2];//存储所有的A+B的值
    20             b[index]=num[i][3]+num[j][4];//存储所有的C+D的值
    21             index++;
    22         }
    23     sort(a+1,a+index);
    24     sort(b+1,b+index);
    25     ll res=0;
    26     /**
    27         A+B+C+D=0 -> C+D=-(A+B)
    28         而C+D的所有值已经预处理好,故可通过二分查找存在于b[]中 -(A+B) 的个数即可
    29     **/
    30     for(int i=1;i < index;++i)
    31     {
    32         int t=lower_bound(b+1,b+index,-a[i])-b;
    33         int k=0;
    34         while(t < index && b[t] == -a[i])//查找 -(A+B) 的个数
    35             k++,t++;
    36         res += k;
    37     }
    38     return res;
    39 }
    40 
    41 int main()
    42 {
    43     while(~scanf("%d",&n))
    44     {
    45         for(int i=1;i <= n;++i)
    46             for(int j=1;j <= 4;++j)
    47                 scanf("%d",&num[i][j]);
    48         printf("%lld
    ",Solve());
    49     }
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    C++解析(5):内联函数分析
    C++解析(4):引用的本质
    C++解析(3):布尔类型与三目运算符
    C++解析(2):进化后的 const 分析
    C++解析(1):C到C++的升级
    net与树莓派的情缘(二)
    net与树莓派的情缘(一)
    Ngin 简单配置文件
    sql geography类型(地理坐标) 赋值
    MongoDB与c#(二)简单例子 使用1.7版本驱动
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/9806272.html
Copyright © 2011-2022 走看看