AT5252题解

注意:这篇题解写给萌新看的,非常详细哦QaQo( ̄▽ ̄)ブ。

题目解释

a a a 数组中中找到 a i a_i ai a j a_j aj a k a_k ak,满足

{ a i + a j = a k a i + a k = a j a j + a k = a i \begin{cases}a_i+a_j=a_k\\a_i+a_k=a_j\\a_j+a_k=a_i \end{cases} ai+aj=akai+ak=ajaj+ak=ai

中的任意一条。

前置芝士:lower_bound

lower_bound 是c++自带的二分的函数,时间复杂度 O ( log ⁡ n ) \mathcal O (\log n) O(logn)(不用说),食用方法是

lower_bound(一个指针,另一个指针,a)

其中这两个指针都在同一个数组里,

它的用处是在第一个指针所指向的数(包括)到第二个指针之间所指向的数中(不包括)第一个大于 n 的数,这两个指针之间的子序列必须是单调不下降的,并返回这个数的地址

使用示例:

int a[]={1,2,3,4,5,6,9,10,1000};
cout<<lower_bound(a,a+n,3)-a;//会输出2

拓展:关于指针

对于一个数组 a,a[0] 的地址可以表达为 a,即

int a[100];
cout<<&a;

会输出 a[0] 的地址。

而且数组的地址是连续的,所以 a[i] 的地址可以表达为 a+i。

思路

solution 1

直接暴力枚举 i i i j j j k k k,但由于 n ≤ 2 × 1 0 3 n \le 2\times10^3 n2×103,时间复杂度 O ( n 3 ) \mathcal O (n^3) O(n3),必定超时。

solution 2

先对数组 a 排序,然后枚举 i i i j j j,然后在 [ j + 1 , n ) [ j+1,n) [j+1,n) 找到最后一个 < i + j < i+j <i+j 的,再将 a n s ans ans 加上(那个数的位置 - j + 1),具体看下面:

1 2 3 4 5 6 7 10 12 15 17
0 0 0 0 i j Y Y  N  N  N

我们观察 > j > j >j 的这一段,具有单调性。

所以二分就行。

code

 sort(a,a+n);
    for(int i=0;i<n-2;i++){
        for(int j=i+1;j<n-1;j++){
            int k=lower_bound(a+j+1,a+n,a[i]+a[j])-a;
            ans+=(k-j-1);
        }
    }
    cout<<ans;

注意&提示:

  • 数组开大一点;
  • lower_bound 第一个参数是 a+j+1;
  • 循环范围: i < n − 2 i<n-2 i<n2 j < n − 1 j<n-1 j<n1

the end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值