[算法]Searching_3 对缺少数的连续数组进行查询

在一场考试中,学生们的分数分布在连续的区间内,分数越低排名越靠前。Sonam提出了关于学生排名和分数的查询,要求通过回答这些查询来解决她的问题。输入包括多个测试案例,每个案例包含组数、查询数以及各组的分数区间。目标是在给定的排名下确定学生的分数。

Searching_3

问题地址

题目描述

Description

They declared Sonam as bewafa. Although she is not, believe me! She asked a number of queries to people regrading their position in a test. Now its your duty to remove her bewafa tag by answering simple queries. All the students who give test can score from 1 to 10^18. Lower the marks, better the rank. Now instead of directly telling the marks of student they have been assigned groups where marks are distributed in continuous intervals, you have been given l(i) lowest mark of interval i and r(i) highest marks in interval i. So marks distribution in that interval is given as l(i), l(i)+1, l(i)+2 . . . r(i)

Now Sonam ask queries in which she gives rank of the student (x) and you have to tell marks obtained by that student

Note: rank1 is better than rank2 and rank2 is better than rank3 and so on and the first interval starts from 1.

Constraints:1<=T<=50,1<=N<=105,1<=Q<=105,1<= l(i) < r(i) <=1018,1<=x<=1018

Input

The first line of input contains an integer T, denoting the no of test cases. Then T test cases follow. Each test case contains two space separated values N and Q denoting the no of groups and number of queries asked respectively. The next line contains N group of two integers separated by space which shows lowest marks in group i ie l(i) and highest marks in group i ie r(i) such that if i < j then r(i) < l(j). The next lines contain Q space separated integers x, denoting rank of student.

Output

For each query output marks obtain by student whose rank is x(1<=x<=10^18).

Sample Input 1

1
3 3
1 10 12 20 22 30
5 15 25

Sample Output 1

5 16 27
题目解析
  1. 给定一个数组,数组中某些位置上没有数

  2. 给定查询,查询数组中第q个数是什么

思路解析

暴力

如果查询q大于当前数组段长度l,那么就令q-=l, 继续查询

如果查询q比小于等于当前数组段长度l,那么就可以返回结果了

可以使用提前缓存结果等方式优化,但暴力其实挺快的

注: 本题可以二分搜索,思路如下
首先统计所有区间,求出第x个区间前共有多少个数,
对q在x进行二分搜索,找到比q小的第一个区间,
( q - 当前区间记录的数) 就是在下一个区间中的第几个数

代码实现

python

if __name__ == '__main__':
    for _ in range(int(input())):
        # _ = input()
        temp = input().strip().split(" ")
        group_num = int(temp[0])
        q_num = int(temp[1])
        arr = list(map(int, input().strip().split(" ")))
        q_arr = list(map(int, input().strip().split(" ")))
        res = []
        for q in q_arr:
            for i in range(0, len(arr) - 1, 2):
                l = arr[i + 1] - arr[i] + 1 # 区间长度
                if q > l:  # 比区间长度大
                    q -= l # 就减掉
                else:  # 在该区间内
                    res.append(str(arr[i] + q - 1))  # 找当前位置的数字
                    break
           #  else:  # 防止题目中只有x个数却让你查询q>x的情况
               #  res.append(str((arr[-1] + q)))
        print(" ".join(res))
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值