博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 2785(折半枚举+二分搜索)
阅读量:4565 次
发布时间:2019-06-08

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

 

题意:

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

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

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

题解:

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

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

AC代码:

1 #include
2 #include
3 #include
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\n",Solve());49 }50 return 0;51 }
View Code

 

转载于:https://www.cnblogs.com/violet-acmer/p/9806272.html

你可能感兴趣的文章
C语言—— for 循环
查看>>
IBM lotus9.0测试版即将公测
查看>>
xml常用方法
查看>>
Cube Stacking(并差集深度+结点个数)
查看>>
AndroidStudio3更改包名失败
查看>>
jq 删除数组中的元素
查看>>
添加按键事件处理及事件处理的参数传递
查看>>
js URL中文传参乱码
查看>>
Leetcode 367. Valid Perfect Square
查看>>
UVALive 3635 Pie(二分法)
查看>>
win系统查看自己电脑IP
查看>>
Backup&recovery备份和还原 mysql
查看>>
全局变量、局部变量、静态全局变量、静态局部变量的区别
查看>>
一道面试题及扩展
查看>>
Unity 3D 我来了
查看>>
setup elk with docker-compose
查看>>
C++ GUI Qt4学习笔记03
查看>>
Java基础回顾 —反射机制
查看>>
c# 前台js 调用后台代码
查看>>
2017-02-20 可编辑div中如何在光标位置添加内容
查看>>