数列问题

题意:
有四个数列 A,B,C,D,每个数列都有 n 个数字。从每个数列中各取出一个数,想知道有多少种方案使得 4 个数的和为 0。当一个数列中有多个相同的数字的时候,把它们当做不同的数对待。
输入:
第一行:n(代表数列中数字的个数) (1≤n≤4000)
接下来的 n 行中,第 i 行有四个数字,分别表示数列 A,B,C,D 中的第 i 个数字(数字不超过 2 的 28 次方)
输出:
输出不同组合的个数。
输入样例:
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
输出样例:
5
解题思路:
四重循环依次枚举会造成n的4次方的致命复杂度,我们对数列两两组合可以将复杂度降到n的2次方。先开四个4000的数组依次存储四个数列,然后16000000的两个数组存储a+b和c+d的组合结果。两重循环得到所有a+b和c+d的组合结果分别存储于ab和cd数组当中。然后先对ab排序,对每一个cd中的c+d的结果,我们取得它的相反数-(c+d),在ab数组中寻找它的个数即可。寻找方法是用二分法查找出大于等于它的第一个数的位置,然后从这个位置开始向后遍历所有满足a+b=-(c+d)的数。把所有的c+d的情况遍历完全即可。
注意事项:
1、用题目上的数据范围提前估计一下需要开的数组的大小,然后在main函数之外开好。
2、第一个大于等于-(c+d)的数也可能是严格大于-(c+d),因此需要判断是否满足a+b=-(c+d)。
总结:
整数二分的典型应用,通过二分法求出大于等于某个数的第一个数的位置。然后比较巧妙地通过很简单的数学变形把四次循环降到两次循环,但是略微增加了空间上的消耗。
参考代码:

#include <iostream>
#include <algorithm>
using namespace std;
int a[4010];
int b[4010];
int c[4010];
int d
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值