FOJ 1858 Super Girl 单调队列
http://acm.fzu.edu.cn/problem.php?pid=1858
一个数组中 找两对元素,第一对元素和最大,第二对元素和最小,限制:一对元素中两个元素的距离在原数组中小于d。去掉这两对元素,剩下的求平均值。
思路:先找两个最大的,暴力枚举第一对元素的最后一个元素,然后维护一个单调减队列,反之 就是维护单调增队列。复杂度O(n).
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<stack> #include<cmath> #include<queue> #include<map> using namespace std; const int INF=0x7fffffff; const double EPS=1e-8; const int maxn=500000+10; int q[maxn],a[maxn],n,d; int main() { while(~scanf("%d%d",&n,&d)) { double ans=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); ans+=a[i]; } int f=1,r=0,last,sum=-INF; q[++r]=1; last=2; while(last<=n) { while(f<=r&&last-q[f]>=d)f++; if(f<=r&&sum<a[q[f]]+a[last])sum=a[q[f]]+a[last]; while(f<=r&&a[last]>=a[q[r]])r--; q[++r]=last++; } ans-=sum; f=1; r=0; sum=INF; last=2; while(last<=n) { while(f<=r&&last-q[f]>=d)f++; if(f<=r&&sum>a[q[f]]+a[last])sum=a[q[f]]+a[last]; while(f<=r&&a[last]<=a[q[r]])r--; q[++r]=last++; } ans-=sum; printf("%.3f\n",ans/(n-4)); } return 0; }