MT3045 松鼠接松果

思路:

求x的一个区间,使区间中的松果的最大y坐标和最小y坐标的差至少为D。若有多个区间,则取最小的那个。

即使用单调队列不断维护最大值和最小值。

首先L固定不动,R不断右移:

即若函数f(R)=max[L,R]-min[L,R] >=D,则此区间满足要求。

之后L往右移一位,R不断右移,找下一个满足条件的区间。

代码: 

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, d, ans = 0x3f3f3f3f;
struct pos
{
    int x, y;
    bool operator<(const pos &a) const
    {
        return x < a.x;
    }
} p[N];
deque<int> maxn, minn;//存储最大值和最小值的索引
int main()
{
    cin >> n >> d;
    for (int i = 1; i <= n; i++)
    {
        cin >> p[i].x >> p[i].y;
    }
    sort(p + 1, p + n + 1); 
    int l = 1;              // 左端点从1开始
    for (int i = 1; i <= n; i++)
    {
        // 确保maxn队列中的y坐标是递增的
        while (!maxn.empty() && p[i].y > p[maxn.back()].y)
            maxn.pop_back();
        maxn.push_back(i);
       // 确保minn队列中的y坐标是递减的
        while (!minn.empty() && p[i].y < p[minn.back()].y)
            minn.pop_back();
        minn.push_back(i);
        //如果满足条件,就更新答案
        while (l < i && p[maxn.front()].y - p[minn.front()].y >= d)
        {
            ans = min(ans, p[i].x - p[l].x);
            l++;
           
            while (!maxn.empty() && maxn.front() < l)
                maxn.pop_front();   
            
            while (!minn.empty() && minn.front() < l)
                minn.pop_front();
        }
    }
    if (ans == 0x3f3f3f3f)
        cout << -1 << endl;
    else
        cout << ans << endl;
    return 0;
}
  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值