POJ 2823 | Sliding Window |
首先 这题因为是在神奇的POJ上, 所以C++和G++可能又有某些玄学差别。
这次是交C++过了, G++T掉。。。
这题就是比较裸的维护一个区间最大值与最小值。
一条宏定义偷师的别人代码(谢谢巨巨)
#include<iostream>
#include <cstdio>
#define ll long long
#define pd (!x && f[tail-1]>a[i]) || (x && f[tail-1]<a[i])
using namespace std;
const int N = 1e6+3;
int n, m, k;
int a[N];
int f[N], in[N];
void getla(int x){
int head , tail;
head = tail = 0;
for(int i=0;i<n;i++){
while(head<tail && (pd)) tail--;
f[tail] = a[i];
in[tail] = i;
tail++;
while(in[head] <= i-k) head++;
if(i>=k-1){
printf("%d%c",f[head],i==n-1?'\n':' ');
}
}
}
int main()
{
scanf("%d%d", &n, &k);
for(int i=0;i<n;i++){
scanf("%d", &a[i]);
}
getla(0);
getla(1);
return 0;
}
FZU 1894 志愿者选拔
这题选择的模型应该是单调递减的队列维护每个人的人品值(每个人还应有一个入队时的序号方便出队)。
这个出队的写出来感觉真的很神奇。
造几个数据自己跑一下大概就能理解。
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1000003;
struct node{
int index;
int rp;
};
node f[N];
void solve(){
char ask[10], name[10];
int head, tail, tprp, cnt = 0, leave =1;
head = tail = 0;
while(scanf("%s", ask)!=EOF){
if(ask[0] == 'E') return ;
if(ask[0] == 'G'){
while(head<tail && f[head].index<=leave)
head++;
leave++;
}
if(ask[0] == 'Q'){
if(head<tail)
printf("%d\n",f[head].rp);
else puts("-1");
}
if(ask[0] == 'C'){
scanf("%s%d", name, &tprp);
while(head<tail && tprp>f[tail-1].rp)
tail--;
f[tail].index = ++cnt;
f[tail++].rp = tprp;
}
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--){
solve();
}
return 0;
}