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