2023年河南CCPC->F题
这是一道有关于滑动窗口的题目
题目链接:https://codeforces.com/gym/104354/attachments
对于这道题可以用两种方法(实则是一种)
1-小根堆中存每两个元素的差值,然后用窗口去滑每一个子区间,遍历找出最小答案
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
#define fi first
#define se second
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N =5e5+10;
int a[N];
priority_queue<PII,vector<PII>,greater<PII>> q;void solve()
{int n,k;cin>>n>>k;for(int i=1;i<=n;i++)cin>>a[i];sort(a+1,a+1+n);for(int i=2;i<=k;i++) q.push({a[i]-a[i-1],i});int ans=1e18;for(int i=k;i<=n;i++){q.push({a[i]-a[i-1],i});while(!q.empty()&&i-k+1>q.top().se)//如果i-k>q.top.se了说明当前的窗口已经不包含这两个元素了{q.pop();}ans = min(ans,q.top().fi*(a[i]-a[i-k+1]));}cout<<ans<<endl;
}
signed main()
{IOSint T=1;
// cin>>T;while(T--) solve(); return 0;
}
2-小根堆中用于存放当前包含a[i]和a[i-1]的窗口,然后遍历每一个差值,找出包含这两个元素的窗口的max的最小值
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
#define fi first
#define se second
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N =5e5+10;
int a[N];
priority_queue<PII,vector<PII>,greater<PII>> q;void solve()
{int n,k;cin>>n>>k;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+1+n);PII mx; mx.fi = a[k]-a[1];mx.se =1;int mi = a[2]-a[1];int ans = mi*mx.fi;q.push(mx);for(int i=2;i<=n;i++){int l = q.top().se;while(!q.empty()&&l+k-1<i){q.pop();l = q.top().se;}mx = q.top();mi = a[i]-a[i-1];ans = min(ans,mx.fi*mi);int x;if(i+k-1<=n) x = a[i+k-1]-a[i];else x = a[n]-a[n-k+1];q.push({x,i});}cout<<ans<<endl;
}
signed main()
{IOSint T=1;
// cin>>T;while(T--) solve(); return 0;
}