尺取法(日志统计和锻造兵器)
1.日志统计
题目描述
小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有 N 行。其中每一行的格式是:ts id
表示在 ts 时刻编号 id的帖子收到一个"赞"。
现在小明想统计有哪些帖子曾经是"热帖"。如果一个帖子曾在任意一个长度为 D 的时间段内收到不少于 K 个赞,小明就认为这个帖子曾是"热帖"。
具体来说,如果存在某个时刻 T 满足该帖在 [T,T+D)这段时间内(注意是左闭右开区间)收到不少于 K个赞,该帖就曾是"热帖"。给定日志,请你帮助小明统计出所有曾是"热帖"的帖子编号。
输入描述
第一行包含三个整数 N,D,K。
以下 N 行每行一条日志,包含两个整数 ts 和 id。
其中,1≤K≤N≤10^5,0≤ts≤10^5,0≤id≤10^5。
输出描述
按从小到大的顺序输出热帖 id。每个 id 一行。
样例输入
7 10 20 10 1010 1010 19 1100 3100
样例输出
13
思路:
1.用到了python的bisect_left()二分查找数据库
用一个set()存储出现的id
用一个list()存储出现的id对应的点赞时间
遍历每一个id,用每一个id的第一个点赞的时间加上间隔时间的d为td,应为是开区间,所以用bisect_left查找比td小的个数,如果个数减去区间左边的值的位置,如果这个数大于k,就输出这个id
from bisect import bisect_leftmaxn=int(1e5+50)n,d,k=map(int,input().split())m=[[] for _ in range(maxn)]post=set()for _ in range(n): ts,idd=map(int,input().split()) post.add(idd) m[idd].append(ts) #读每个帖子的赞的时间post = sorted(post) #对帖子id排序for idd in post:#检查每个帖子 m[idd]=sorted(m[idd]) #把某个帖子的ts排序 for i in range(len(m[idd])): #暴力统计这个帖子是不是热帖 td = m[idd][i]+d if(bisect_left(m[idd],td)-i >= k): print(idd) break
2.锻造兵器
题目描述
小明一共有 n 块锻造石,第 i 块锻造石的属性值为 ai。
现在小明决定从这 n 块锻造石中任取两块来锻造兵器。
通过周密计算,小明得出,只有当两块锻造石的属性值的差值等于 C,兵器才能锻造成功。
请你帮小明算算,他有多少种选取锻造石的方案可以使得锻造成功。
输入描述
第一行包含两个整数 n,C,其含义如题所述。
接下来一行包含 n 个整数,分别表示 a1,a2,⋯,an。
1≤N≤2×10^5,∣ai∣≤10^4,0≤C≤10^9。
输出描述
输出共一行,包含一个整数,表示答案。
输入输出样例
示例 1
输入
6 38 4 5 7 7 4
输出
5
双指针 (超时啦)
n,c=map(int,input().split())li=list(map(int,input().split()))li=sorted(li)res=0for i in range(1,len(li)): for j in range(i-1,-1,-1): if abs(li[j]-li[i])==c: res+=1 if abs(li[i]-li[j])>c: breakprint(res)