> 文档中心 > 尺取法(日志统计和锻造兵器)

尺取法(日志统计和锻造兵器)


1.日志统计 

题目描述

小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有 N 行。其中每一行的格式是:ts id

表示在 ts 时刻编号 id的帖子收到一个"赞"。

现在小明想统计有哪些帖子曾经是"热帖"。如果一个帖子曾在任意一个长度为 D 的时间段内收到不少于 K 个赞,小明就认为这个帖子曾是"热帖"。

具体来说,如果存在某个时刻 T 满足该帖在 [T,T+D)这段时间内(注意是左闭右开区间)收到不少于 K个赞,该帖就曾是"热帖"。给定日志,请你帮助小明统计出所有曾是"热帖"的帖子编号。

输入描述

第一行包含三个整数 N,D,K。

以下 N 行每行一条日志,包含两个整数 ts 和 id。

其中,1≤KN≤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)