题意:
有n个数,求可容纳k个数的区间从头移到末尾,每次都得到一个区间最大值和最小值,输出区间移动完成后的最大值和最小值集合。
题目条件:
n ≤ 10^6,k可能比n大。
解法一:
建立最大值优先队列和最小值优先队列,然后加入包含值和地址的结构体变量,根据题意模拟即可。
主要代码:(有些宏定义部分懒得改了。。。)
int n,k;
class node1{
public:
int value,key;
bool operator<(const node1& t)const{
return value<t.value;//zeng
}
};
class node2{
public:
int value,key;
bool operator>(const node2& t)const{
return value>t.value;//jian
}
};
void solve(){
VI a(n);
priority_queue<node1> s1;
priority_queue<node2, vector<node2>, greater<node2> >s2;
int cnt=0;
REP1(i,n){
scanf("%d",&a[i]);
if(cnt<k){
node1 temp;
node2 temp2;
temp.value=a[i],temp.key=i;
temp2.value=a[i],temp2.key=i;
s1.push(temp);
s2.push(temp2);
}
cnt++;
}
int l=0,r=k-1;
VI mins,maxs;
while(r<n){
node1 temp1=s1.top();
node2 temp2=s2.top();
while(!s1.empty()&&temp1.key<l){
s1.pop();
temp1=s1.top();
}
while(!s2.empty()&&temp2.key<l){
s2.pop();
temp2=s2.top();
}
maxs.push_back(temp1.value);
mins.push_back(temp2.value);
l++,r++;
node1 t1;
node2 t2;
t1.value=a[r],t1.key=r;
t2.value=a[r],t2.key=r;
s1.push(t1),s2.push(t2);
}
REP1(i,mins.size()){
if(i)
printf(" ");
printf("%d",mins[i]);
}
printf("\n");
REP1(i,maxs.size()){
if(i)
printf(" ");
printf("%d",maxs[i]);
}
printf("\n");
}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0);
while(~scanf("%d%d",&n,&k))
solve();
return 0;
}
其他解法待学习。。。