半平面交 [ZJOI2008][HYSBZ\BZOJ1038]瞭望塔__計算幾何

來源:互聯網
上載者:User
題目連結 分析 看穿題目

考慮組成村莊的每一條線段,顯然,我們要在這條線段所在直線上方的半平面內才能看見它。所以,瞭望塔必須要在所有組成村莊的線段的所在直線的上方的半平面的交集內,才能

從瞭望塔的頂端可以看到H村的任意位置

所以,這道題就是求村莊的地面到這個半平面交的最短距離。 實現方式

很多同學看到半平面交就覺得代碼一定十分高(e)端(xin)。但是這道題的半平面交十分特殊。
讓我們先看看這道例題。 例題

例題連結:【計算幾何】[HNOI2008][HYSBZ/BZOJ1007]水平可見直線
例題和這道題中的半平面都是在直線的上方。
例題是求組成半平面交的線段所在的直線是哪些。 回到這道題 具體做法

這道題也可以用同樣的方式求出半平面交。
組成半平面交和地面的都是線段,可看做分段函數。
令半平面交的函數為 f(x) f(x),地面為 g(x) g(x).
h(x)=f(x)−g(x) h(x)=f(x)-g(x)
ans=min(h(x)) ans=min(h(x))
考慮這f(x),g(x)兩個分段函數,每一段都是一次函數,h(x)顯然也是一次函數,分段的分界點顯然就是f(x),g(x)兩個函數的分界點。
而一次函數的極值顯然在 端點(分界點)處取得。

bingo

我們只需要枚舉f(x),g(x)的分界點,然後計算在分界點處的h(x)的值即可,只需要 O(n) O(n)的時間複雜度。

總時間複雜度 O(nlogn) O(nlogn)(排序的時間複雜度) 代碼

#include<cstdio>#include<algorithm>#include<cmath>#define MAXN 300using namespace std;#define EPS 1e-9#define INF 1e27struct node{    double k,b;    bool operator<(const node &x)const{        if(fabs(k-x.k)<EPS)            return b>x.b;        return k<x.k;    }    bool operator==(const node &x)const{        return fabs(k-x.k)<EPS;    }}a[MAXN+10],b[MAXN+10];struct point{    double k,b,x,y;    point(){    };    point(node a,double xx,double yy){        x=xx,y=yy,k=a.k,b=a.b;    }}p[MAXN+10];int n,x[MAXN+10],y[MAXN+10],na,np;double ans=INF;void Read(int &x){    char c;    bool f=0;    while(c=getchar(),c!=EOF){        if(x=='-')            f=1;        if(c>='0'&&c<='9'){            x=c-'0';            while(c=getchar(),c>='0'&&c<='9')                x=x*10+c-'0';            ungetc(c,stdin);            if(f)                x=-x;            return;        }    }}void read(){    int i;    Read(n);    for(i=1;i<=n;i++)        Read(x[i]);    for(i=1;i<=n;i++)        Read(y[i]);    for(i=1;i<n;i++){        b[i].k=1.0*(y[i]-y[i+1])/(x[i]-x[i+1]);        b[i].b=y[i]-x[i]*b[i].k;        a[i]=b[i];    }    sort(a+1,a+n);    na=unique(a+1,a+n)-a-1;}void ints_halfplane(){    int i,j,ti;    double tx,x;    for(i=1;i<na;){        x=INF;        for(j=i+1;j<=na;j++){            tx=(a[j].b-a[i].b)/(a[i].k-a[j].k);            if(tx<=x)                ti=j,x=tx;        }        p[++np]=point(a[i],x,x*a[i].k+a[i].b);        i=ti;    }    p[++np]=point(a[na],INF,0);}void solve(){    int i,j;    ints_halfplane();    for(i=j=1;i<=np&&j<=n;){        if(p[i].x<x[j]){            ans=min(p[i].y-b[j-1].k*p[i].x-b[j-1].b,ans);            i++;        }        else{            ans=min(p[i].k*x[j]+p[i].b-y[j],ans);            j++;        }    }}int main(){    read();    solve();    printf("%.3lf",ans);}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.