题解-动态第K小问题

描述

输入
第一行给出一个数字T,代表T组数据 第二个先给出N,代表数列中有多少个数字,再给出M,代表M个询问。 N,M<=30000 第三行给出N个数字 第四行给出M个数字,b1,b2…bm,保证升序。 代表依次询问前b1中数字中第1小的数字是多少,前b2个数字中第2小的数字是多少,前b3个数字中第3小的数字是多少

输出
针对每个询问,输出结果。

样例
输入复制
1
7 4
1 3 2 4 5 9 8
2 3 4 5
输出复制
1
2
3
4


末尾几行是对输出格式的一个转换,记住要加上那个:

		if(T>0)printf("\n");

因为在T>0时才有值输出,否则过不了。

#include<bits/stdc++.h>
using namespace std;
int a[30005],b[30005];
int n,m,j,T;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		priority_queue<int> q2;
		priority_queue<int, vector<int>, greater<int> > q1;
		j=1;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		for(int i=1;i<=m;i++)
			scanf("%d",&b[i]);
		for(int i=1;i<=m;i++)
		{
			for(;j<=b[i];j++)
				q1.push(a[j]);
			q2.push(q1.top());
			q1.pop();
			while(!q1.empty()&&q1.top()<q2.top())
			{
				int x=q1.top();
				int y=q2.top();
				q1.pop();
				q2.pop();
				q1.push(y);
				q2.push(x);
			}
			printf("%d\n",q2.top());
		}
		if(T>0)printf("\n");
	}
	return 0;
}
### HNUCMOJ平台上的第K小问题解析 对于求解数中的第K小素这一类问题,可以采用多种算法来实现。一种高效的方法是利用快速选择算法,该方法基于快速排序的思想,在平均情况下能够在线性时间内完成查找操作。 #### 方法一:使用快速选择算法 快速选择是一种用于解决此类问题的选择算法,其核心思想是在不完全排序的情况下找到目标位置的素[^1]。 ```python import random def partition(nums, left, right): pivot = nums[left] l = left + 1 r = right while True: while l <= r and nums[l] < pivot: l += 1 while l <= r and nums[r] > pivot: r -= 1 if l >= r: break nums[l], nums[r] = nums[r], nums[l] l += 1 r -= 1 nums[left], nums[r] = nums[r], nums[left] return r def quick_select(nums, k): if not nums: return None pos = partition(nums, 0, len(nums) - 1) if pos + 1 == k: return nums[pos] elif pos + 1 > k: return quick_select(nums[:pos], k) else: return quick_select(nums[pos+1:], k-pos-1) nums_example = [7, 10, 4, 3, 20, 15] k = 3 print(f"The {k}rd smallest element is {quick_select(nums_example.copy(), k)}") ``` 此代码实现了`quick_select`函数,它接收一个列表和整数k作为参数,并回给定列表中第k小的素。注意这里为了不影响原数据进行了深拷贝处理[^1]。 另一种更简单但效率较低的方式是先对整个序列进行升序排列再直接访问索引为\(k-1\)处的值;然而这种方法的时间复杂度较高,尤其是在面对大数据集时表现不佳。 #### 方法二:堆排序的应用 除了上述提到的技术外,还可以考虑构建最小堆或最大堆结构来进行优化。当只需要获取前几个最小/最大的项时,维护一个小根堆是非常有效的策略之一[^2]。 ```python import heapq def find_kth_smallest_heapq(nums, k): heap = [] for num in nums: heapq.heappush(heap, num) result = None for _ in range(k): result = heapq.heappop(heap) return result nums_example = [7, 10, 4, 3, 20, 15] k = 3 print(f"The {k}rd smallest element using heap is {find_kth_smallest_heapq(nums_example, k)}") ``` 这段Python脚本展示了如何通过内置模块heapq创建并管理优先队列(即最小堆),从而轻松找出所需的第k小数值[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值