算法-枚举、模拟与排序-1236. 递增三元组

题目

思路

  1. 本题有三种思路:可以先通过暴力搜索,再进行优化:二分,前缀和,双指针AcWing 1236. 递增三元组 (二分+双指针+前缀和) - AcWing
  2. 注意点:枚举的顺序和优化;优化在于对性质的探索,进而进行优化
  3. 蓝桥杯中全部使用暴力搜索也可以得到可观的分数
  4. 优化:最多枚举一个数组:B
    1. 枚举A和C是等价的,但是枚举这两者,剩下两者不是完全独立的,无法用乘法公式直接相乘。故先枚举B
    2. 对于每个Bj:(1)在A中有多少个小于Bj(2)在C中有多少个大于Bj
    3. 方法一 ==》前缀和:在A中有多少个小于Bj ==》求[0,Bj-1]有多少个数 ==》从[0,Bj-1]的和,有出现为1,没出现为0
      1. cnt[i]:A中i这个值出现的次数 ==》cnt[A[i]]
      2. s[] ==》s[i]=cnt[0]+cnt[1]+...+cnt[i]:在A数组中0-i出现多少次
      3. 在A中有多少个小于Bj:s[Bj-1]
    4. 方法二 ==》排序+二分
    5. 方法三 ==》排序+双指针

代码

双指针:

# 双指针算法 ==》时间过不去
n=int(input())
A=list(map(int,input().split()))
B=list(map(int,input().split()))
C=list(map(int,input().split()))
A.sort()
B.sort()
C.sort()
res=0
for i in range(0,n):
    a=0
    c=0
    for j in range (n):
        if A[j]<B[i]:
            a+=1
    for k in range (n):
        if C[k]>B[i]:
            c+=1
    res+=a*c
print(res)

前缀和:时间仍需优化

    n = int(input())
    A = list(map(int, input().split()))
    B = list(map(int, input().split()))
    C = list(map(int, input().split()))

    cnta = [0] * (10**5 + 10)
    cntc = [0] * (10**5 + 10)
    sa = [0] * (10**5 + 10)
    sc = [0] * (10**5 + 10)

    for i in range(n):
        cnta[A[i]] += 1
        cntc[C[i]] += 1

    sa[0] = cnta[0]
    for i in range(1, len(sa)):
        sa[i] = sa[i - 1] + cnta[i]

    sc[0] = cntc[0]
    for i in range(1, len(sc)):
        sc[i] = sc[i - 1] + cntc[i]

    ans = 0
    for i in range(n):
        b = B[i]
        ans += sa[b - 1] * (sc[-1] - sc[b])
    print(ans)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值