题面描述
给定n个数
a1,…,an,高老师想了解al,…,ar中有多少对相邻元素值相同。高老师把这个数目定义为区间[l,r]的价值,用v[l,r]表示。例如 1,1,1,2,2 这五个数所组成的区间的价值为3。
现在高老师想知道在所有的v[l,r] (1≤l≤r≤n)中,第k小的值是多少。但高老师要和女朋友出去玩,于是他把这个问题甩给了你,请你帮他解决一下。
输入数据
第一行有一个整数t(1≤t≤30),表示有t组数据。
对于每组数据:
第一行有两个整数n,k (1≤n≤2000,1≤k≤n(n+1)/2);
第二行有n个整数a1,…,an (1≤ai≤109)。
输出数据
对于每组数据:输出一个整数,表示第 k小的值。
样例输入
2
4 7
1 1 2 3
3 5
100 100 100
样例输出
0
1
心得:
1.n个数有n(n+1)/2个区间,因为单独一个数也是一个区间
2.二分法,将数据折半,减少搜索次数
3.尺取法(像贪吃蛇一样向前移动),找出小于等于某值(二分法中值) 的区间个数
4.通过 0 1 重写 数组
def getRangeN(mid,nums,n):
rangeN = 0
p = 0
sumRange = 0
for i in range(n):
while p < n:
if sumRange <= mid:
sumRange += nums[p]
p += 1
else:
break
sumRange -= nums[i]
rangeN += p - i
return rangeN
T = int(input())
for t in range(T):
n, k = list(map(int, input().split()))
s = [int(item) for item in input().split()]
nums = []
for i in range(1, len(s)):
if s[i]==s[i-1]:
nums.append(1)
else:
nums.append(0)
nums.append(0)
left = 0
right = n-1
while left < right:
mid = int((left+right)/2)
if(getRangeN(mid,nums,n)>=k):
right=mid
else:
left=mid+1
print(left)