P2698 [USACO12MAR]花盆Flowerpotnode
題意:c++
給出水滴的座標與下落時間,你須要構造一個盆,使他的寬度知足
在其範圍內可以接住水滴時間(第一滴和最後一滴/最大與最小值)時間差大於等於k,且使得這個盆的直徑最小ide
思路:spa
會想到尺取法(雙指針)來在符合條件內縮小範圍,同時又涉及到區間最值問題,那麼上來想就很容易想到單調隊列或者單調棧來維護區間最值
兩點:知足區間最小與最大之差大於k,且使得其長度最小。
(1)區間最值:因爲是要進行雙指針操做:因此選擇雙端隊列來實現單調隊列維護最值,且能維護在 q.front().x ~ q.back().x的區間最值指針
(2)在符合條件下對 front/隊首進行移動,以達到縮小區間操做code
code:blog
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+7; const int inf = 0x3f3f3f3f; struct node{ int x,y; }; bool cmp(node a,node b){ return a.x<b.x; } node arr[maxn]; deque<node>q1; deque<node>q2; int main(){ int n,k; cin>>n>>k; for(int i=0;i<n;i++){ cin>>arr[i].x>>arr[i].y; } sort(arr,arr+n,cmp); int ans = inf; for(int i=0;i<n;i++){ node tmp; //維護最大最小單調隊列 while(!q1.empty()&&q1.back().y<arr[i].y) q1.pop_back(); tmp = arr[i]; q1.push_back(tmp); while(!q2.empty()&&q2.back().y>arr[i].y) q2.pop_back(); q2.push_back(tmp); while(!q1.empty()&&!q2.empty()&&q1.front().y-q2.front().y>=k){ node pos; if(q1.front().x<q2.front().x) {pos = q1.front(); q1.pop_front();} else {pos = q2.front(); q2.pop_front();} ans = min(ans,arr[i].x-pos.x); } } if(ans!=inf) cout<<ans<<endl; else cout<<-1<<endl; }