来源:POJ2823
这一题对于时间还是挺紧的,所以这个方法很巧妙。
这是我Tle
#include <iostream>
#include <cstdio>
#include <map>
#include <queue>
#include <stack>
using namespace std;
const int MAXN=1000010;
int a[MAXN];
int mina[MAXN],maxn[MAXN];
priority_queue<int,vector<int>,greater<int> >p1;
priority_queue<int,vector<int>,less<int> >p2;
stack<int>s;
int main(){
int n,k,i;
scanf("%d%d",&n,&k);
for(i=0;i<n;i++){
scanf("%d",a+i);
}
for(i=0;i<k;i++)
{
p1.push(a[i]);
p2.push(a[i]);
}
for(i=0;i<n-k+1;i++){
maxn[i]=p2.top();
mina[i]=p1.top();
while(p2.top()!=a[i]){
s.push(p2.top());
p2.pop();
}
p2.pop();
while(!s.empty()){
p2.push(s.top());
s.pop();
}
while(p1.top()!=a[i]){
s.push(p1.top());
p1.pop();
}
p1.pop();
while(!s.empty()){
p1.push(s.top());
s.pop();
}
p1.push(a[i+k]);
p2.push(a[i+k]);
}
for(i=0;i<n-k;i++)
{
printf("%d ",mina[i]);
}
printf("%d\n",mina[i]);
for(i=0;i<n-k;i++)
{
printf("%d ",maxn[i]);
}
printf("%d\n",maxn[i]);
return 0;
}
中间用一个栈存了弹出来的东西,然后重新弹出第一个,在重新压进去,当时想出来觉的能节约不少时间,其实是太天真了。两个优先队列来回弹,复杂度比在区间刷一遍都高!!!真是天真了。
这个问题对于优先队列的用法真是大开眼界,就是用优先队列来存指针(数组下标),维护的值是a[]中的值,我在代码里面说。当然,这个时候就要自己写cmp了,不用用greater、less水水。还有就是,注意那个数组大小要数清楚了,因为这个还RE了一发。
我在代码注释里面说好了。
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
const int MAXN=10000100;
int a[MAXN];
int aa[MAXN],bb[MAXN];
struct cmp1{
bool operator()(const int x,const int y){
return a[x]>a[y];
}
};
struct cmp2{
bool operator()(const int x,const int y){
return a[x]<a[y];
}
};
//上面两个就是,维护a数组的排序的指针的两个优先队列
priority_queue<int ,vector<int> ,cmp1>p1;
priority_queue<int ,vector<int> ,cmp2>p2;
int main(){
int n,k;
scanf("%d%d",&n,&k);
int i;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<k;i++)
{//前i个,这个时候a数组没有排序,但是我已经知道具体的顺序了
p1.push(i);
p2.push(i);
}
int cnt1,cnt2;
cnt1=cnt2=0;
aa[cnt1++]=a[p1.top()];
bb[cnt2++]=a[p2.top()];
//这两个数组显然是表示最后的结果,先将前K的最大最小放进去,容易理解
for(i=k;i<n;i++){
p1.push(i);
p2.push(i);
//压进去后面的,好理解
//下面就是日了本鶸的两步啊
/*i-p1.pop()就是说,我没有必要考虑一定要让之前的那个元素出去,只要它不是最大或者最小值,我都没必要弹出,保留在里面没有关系,如果i-p1.pop()是>=k了,就说明这个解不在里面了,我直接去掉好了,再找一个最小值,非常精彩的做法
*/
while(i-p1.top()>=k)
p1.pop();
aa[cnt1++]=a[p1.top()];
while(i-p2.top()>=k)
p2.pop();
bb[cnt2++]=a[p2.top()];
}
//下面废话,群巨都会,不说了
for(i=0;i<n-k;i++)
{
printf("%d ",aa[i]);
}
printf("%d\n",aa[i]);
for(i=0;i<n-k;i++)
{
printf("%d ",bb[i]);
}
printf("%d\n",bb[i]);
return 0;
}