poj 3334 計算幾何

來源:互聯網
上載者:User

有一個連通器,由兩個漏鬥組成,倒vol提及的水,問你連通器中水的高度是多少

解法:先求出水面可以到達的最低和最高的高度,然後二分答案判斷

View Code

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const double eps = 1e-8;const int maxn = 1010;const double inf = 1000000000;int n,m;double vol,miny,maxy,ans;struct Point{    double x,y;    Point(){};    Point(double x,double y){        this->x=x;        this->y=y;    }    void read(){        scanf("%lf%lf",&x,&y);    }}P[maxn],Q[maxn];double min(double a,double b){    return a<b?a:b;}int sign(double x){    return (x>eps)-(x<-eps);}void input(){    int i;    miny=inf;    scanf("%lf",&vol);    scanf("%d",&n);    for(i=0;i<n;i++) {        P[i].read();        if(sign(P[i].y-miny)<0)  miny=P[i].y;    }    scanf("%d",&m);    for(i=0;i<m;i++){        Q[i].read();        if(sign(Q[i].y-miny)<0)  miny=Q[i].y;    }    maxy=min(min(P[0].y,P[n-1].y),min(Q[0].y,Q[m-1].y));}double getarea(Point *p,int n){    int i;    double area=0;    for(i=0;i<n;i++) area+=p[(i+1)%n].y*(p[i].x-p[(i+2)%n].x);    return fabs(area/2);}bool cross(Point a,Point b,double y){    return sign(a.y-y)*sign(b.y-y)<=0;}Point intersect(Point p1,Point p2,Point p3,Point p4){    Point p;    double a1,b1,a2,b2,c1,c2,d;    a1=p1.y-p2.y; b1=p2.x-p1.x; c1=p1.x*p2.y-p2.x*p1.y;    a2=p3.y-p4.y; b2=p4.x-p3.x; c2=p3.x*p4.x-p4.x*p3.y;    d=a1*b2-a2*b1;    p.x=(-c1*b2+c2*b1)/d;    p.y=(-a1*c2+a2*c1)/d;    return p;}Point cut[maxn];int tot;double getvol(double y,int n,Point P[]){    int i,j,k;    tot=0;    Point a=Point(0,y),b=Point(1,y);    for(i=0;i<n-1;i++){        if(cross(P[i],P[i+1],y)){            cut[tot++]=intersect(P[i],P[i+1],a,b);            break;        }    }    for(j=i+1;j<n-1;j++){        cut[tot++]=P[j];        if(cross(P[j],P[j+1],y)){            cut[tot++]=intersect(P[j],P[j+1],a,b);            break;        }    }    double area=getarea(cut,tot);    return area;}double gao(double y){    double a,b;       a=getvol(y,n,P);       b=getvol(y,m,Q);       return a+b;}void solve(){    double l=miny,r=maxy,mid;    while(fabs(l-r)>eps){        double mid=(l+r)/2;        double test=gao(mid);        int flag=sign(test-vol);        if(flag<=0){            ans=mid;            l=mid;        }        else  r=mid;    }}int main(){    int t,i,j;    scanf("%d",&t);    while(t--){        input();        solve();        printf("%.3lf\n",ans);    }    return  0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.