植木鉢

トピックポータル

推測では、任意の方法により、スライディングウィンドウ(例えば、バイナリの答え)に変換するかどうかを確認するためにモノトーンのキューを解く場合は最も典型的には、ウィンドウをスライディングモノトーンキューまたはトピックは、使用することができます。いくつかのトピックは、STテーブルによって解決することができるかのような質問は、一般的な問題単調キューの最大値と最小値を扱っ。
キューが(単調ハードキューに入れ...)単調に行ったように、この質問が知られている
が見つかりました:質問の意味を簡単にするために、\は(X \)その差が縦よりも大きいか等しくなるように、最も近い2点間の差異を調整\(D \)
最初のポイントに従い、(X \ \) 昇順で
2つのアイデアを開始:

各点の列挙を、(その答えは列挙しなければなりません)低い点と、それを考える:1を考えます。これは、(再度の右側に後方ケース)その点よりも高い探して、それを残しました。単調減少シーケンスを維持\(X \)ように順序付けられたキューに残っ複数するよう単調点遠い現在の点において、より高いです。だから、2の分離(または直接列挙)資格\(y軸の\) 現在地点からの距離と、答えを更新します。
半分の回答:2を考える\(Lの\を)、または各点を列挙、(その答えは列挙しなければならない)、低ポイントと考えます。これは、(再度の右側に後方ケース)その点よりも高い探して、それを残しました。単調減少シーケンスを維持\(X \)ように順序付けられたキューに残っ複数するよう単調点遠い現在の点において、より高いです。したがって、2つの分離\(X \)のために等しい未満であり、この点に係る(Lの\)\キューにおける単調左端点を、限り、それらは縦座標として、両者の差がより大きいか等しい(D \)\するために、(戻る\ \ ) \(trueに\) 何がなかった場合は、\(リターン\) それは現実的ではありません。

2つのコードの唯一のアイデアを書きます:

#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;
}

別のアルゴリズムを終え、気持ちは同じアルゴリズムと別のエラーですが、右の変更変更、またはしないように長い時間のために帰ってきました。

両者の分離:問題の解決策を考えて\(Lの\) 各々が左から右への長さを求める\(Lの\)を満足条件があるかどうかを確認するために、最大値と最小間隔(スライディングウィンドウ)のを。

ときに最初の投稿90分:
ここでは、画像の説明を入力します。
100:
ここでは、画像の説明を入力します。

ACコード:

#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;
}

おすすめ

転載: www.cnblogs.com/karryW/p/11374030.html