当前位置: 代码迷 >> 综合 >> C - Prefix K-th Max (c++ stl)
  详细解决方案

C - Prefix K-th Max (c++ stl)

热度:17   发布时间:2023-12-05 16:29:46.0

翻译过来是:

问题陈述

给定的是一个排列P=(P_1,P_2,\ldots,P_N)P=(P1?,P2?,…,PN?)关于(1,2,\ldots,N)(1,2,…,N)和一个正整数K.

对于每个i=K,K+1,\ldots,Ni=K,K+1,…,N,找到以下内容。

  • 这KK-第一个中最大的值i条款P.

限制

  • 1次10^51≤K≤N≤5×105
  • (P_1,P_2,\ldots,P_N)(P1?,P2?,…,PN?)是的排列(1,2,\ldots,N)(1,2,…,N).
  • 输入中的所有值都是整数。

投入 输出
3 2
1 2 3
1
2
  • 这(K=)(K=) 22-第一个中第二大值22条款PP, (P1,p2)=(1,2)(P1?,P2?)=(1,2),是11.
  • 这(K=)(K=) 22-第一个中第二大值33条款PP, (P1,p2,P3)=(1,2,3)(P1?,P2?,P3?)=(1,2,3),是22.

投入

11 5
3 7 2 5 11 6 1 9 8 10 4
输出
2
3
3
5
6
7
7
这个题的意思是 第一次输出:从第一个到第k个数,排序之后第k大的数,第二次输出:从第一个数到第k+1个数,排序之后第k大的数,第三次输出第一个数到第k+2个数,排序之后第k大的数...知道最后输出第一个数到第n个数,排序之后第k大的数。

思路:如果按照平常的解法,加入一个数排一次序肯定会超时,所以这时候就用到stl里的优先队列来自动排好序,然后再找规律,第一次是从第一个开始到第k个数输出第k大的数,实际上就是从小到大排序之后的第一个数,再加入一个数之后第k大的数就是排序好的第2个数,为了方便操作,我们利用stl直接将排序之后的第一个数也就是队头删除之后再输出队头的数,刚好就是没删除之前的第二个数,然后插入第三个数的时候再删除队头,然后输出队头,就是全都没删除时的第三个数...以此类推。

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int n,k,num,i;
priority_queue<int,vector<int>,greater<int> > a;//定义小根堆 
int main(){scanf("%d %d",&n,&k);for(i=0;i<k;i++){scanf("%d",&num);a.push(num);}//先把前k个数输入a printf("%d\n",a.top());for(i=k;i<n;i++){scanf("%d",&num);a.push(num);//一个一个插入 a.pop();//插入之后删除最小的 printf("%d\n",a.top());//输出删除之后最大的 }return 0;
}