flower pot

Topic Portal

Monotone queue or topic sliding window Most typically, can be used if the guess solving monotone queue to see if converted into the sliding window (e.g., binary answer) by any method. Questions dealt with general issues monotonous queue maximum and minimum values, as if some topics can be solved by ST table.
This question is known as the queue was done monotonically (monotonously queues hard ...)
to simplify the meaning of the questions: found \ (X \) coordinate difference between the nearest two points, so that their difference is greater than or equal ordinate \ (D \)
(in accordance with the first point (x \ \) in ascending order)
beginning two ideas:

Thinking one: enumeration of each point, think of it as the low point (so the answer must be to enumerate). This left it looking higher than its point (the case backwards to the right of it again). Maintains a monotonically decreasing sequence as \ (X \) so ordered, more to the left in the queue so monotonous point farther in the current point, and higher. So the separation of two (or direct enumeration) a qualified \ (the y-\) , with its distance from the current point and update the answer.
Thinking two: half an answer \ (L \) , or enumerate each point, think of it as the low point (so the answer must be to enumerate). This left it looking higher than its point (the case backwards to the right of it again). Maintains a monotonically decreasing sequence as \ (X \) so ordered, more to the left in the queue so monotonous point farther in the current point, and higher. Therefore, two separated \ (X \) according to this point is less than equal to \ (L \) monotonically leftmost point in the queue, the difference between the two as long as they ordinate is greater than or equal \ (D \) , to \ (return \ ) \ (to true \) . If there has been no \ (return \) , then it is not feasible.

Write only the idea of ​​two codes:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define mid ((l+r)>>1)
#define midd ((ll+rr)>>1)
using namespace std;
const LL N = 100005;
LL n,D,maxx,minn=1000006,l=1,r;
LL maxxl,minnl=1000006,ans;
struct node{
    LL x,y;
    bool friend operator < (const node& a,const node& b)
    { return a.x<b.x; }
}a[N],q[N];
LL aaa[40000000];
inline int read()
{
    int ans=0,w=1;
    char c=getchar();
    while((c<'0'||c>'9')&&c!='-') c=getchar();
    if(c=='-') { w=-1; c=getchar(); }
    while(c>='0'&&c<='9')
    { ans=ans*10+c-'0'; c=getchar(); }
    return ans*w;
}
bool check(LL u)
{
    l=1,r=0;
    for(LL i=1;i<=n;i++)
    {
        while(q[r].y<=a[i].y&&r) --r;
        LL ll=1,rr=r,ansp=-1;
        while(ll<=rr)
        {
            if(a[i].x-q[midd].x<=u) ansp=midd,rr=midd-1;
            else ll=midd+1;
        }
        if(q[ansp].y-a[i].y>=D&&ansp>0) return true;
        q[++r].x=a[i].x;
        q[r].y=a[i].y;
    }
    l=1;r=0;
    for(LL i=n;i>=1;i--)
    {
        while(q[r].y<=a[i].y&&r) --r;
        LL ll=1,rr=r,ansp=-1;
        while(ll<=rr)
        {
            if(q[midd].x-a[i].x<=u) ansp=midd,ll=midd+1;
            else rr=midd-1;
        }
        if(q[ansp].y-a[i].y>=D&&ansp>0) return true;
        q[++r].x=a[i].x;
        q[r].y=a[i].y;
    }
    return false;
}
int main()
{
//  freopen("a.in","r",stdin);
//  freopen("a.out","w",stdout);
//  cin>>n>>D;
//  scanf("%lld%lld",&n,&D);
    n=read(); D=read();
    for(LL i=1;i<=n;i++)
    {
        scanf("%lld%lld",&a[i].x,&a[i].y);
        minn=min(minn,a[i].y);
        maxx=max(maxx,a[i].y); 
        minnl=min(minnl,a[i].x);
        maxxl=max(maxxl,a[i].x); 
    }
//  cout<<maxx<<"*"<<minn<<endl;
    if(maxx-minn<D) { printf("-1\n"); return 0; }
    sort(a+1,a+n+1);
    LL l=1,r=maxxl-minnl;
    ans=r;
    while(l<=r)
    {
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%lld\n",ans);
    return 0;
}

Finished another algorithm, is back for a long time to change, or not change right, although the feeling is the same algorithm and another error.

Thinking problem solution: the separation of a two \ (L \) , each seek length from left to right \ (L \) of the maximum and the minimum interval (sliding window), to see if there are satisfied condition.

When the first post 90 minutes:
enter image description here
100:
enter image description here

AC Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1) 
using namespace std;
const int N = 100005;
const int inf = 2147483647;
int n,D,l1=1,r1,l2=1,r2;
int ans,min1=inf,min2=inf,max1,max2;
struct node{
    int x,y;
    // bool friend operator <(const node& a,const node& b)
    // { return a.x<b.x; }
}a[N],q1[N],q2[N];
bool cmp(node a,node b)
{ return a.x<b.x; }
bool check(int u)
{
    l1=l2=1; r1=r2=0; 
    for(int i=1;i<=n;i++)
    {
        while(l1<=r1&&a[i].x-q1[l1].x>u) ++l1;
        while(l2<=r2&&a[i].x-q2[l2].x>u) ++l2;
        while(q1[r1].y<=a[i].y&&r1) --r1;
        while(q2[r2].y>=a[i].y&&r2) --r2;
        q1[++r1].x=a[i].x; q1[r1].y=a[i].y;
        q2[++r2].x=a[i].x; q2[r2].y=a[i].y;
        if(q1[l1].y-q2[l2].y>=D) return true;
    }
    return false;
}
int main()
{
    scanf("%d%d",&n,&D);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y);
        min1=min(min1,a[i].x);
        min2=min(min2,a[i].y);
        max1=max(max1,a[i].x);
        max2=max(max2,a[i].y);
    }
    if(max1-min1<D) { printf("-1\n"); return 0 ;}
    sort(a+1,a+n+1,cmp);
    int l=1,r=max1-min1;
    while(l<=r)
    {
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/karryW/p/11374030.html