POJ 2540 Hotter Colder(半平面交求可行域)

來源:互聯網
上載者:User

轉載請註明出處,謝謝http://blog.csdn.net/acm_cxlove/article/details/7854526      
by---cxlove

題目:從0,0出發,走到某一點,會告訴你目標點是更近了還是更遠了,每走一步求出目標的可能範圍地區面積

http://poj.org/problem?id=2540

給出兩點,已知哪點更近,也就是將地區用中垂線分開,便可以確定解在哪個地區範圍之內

首先是根據兩個點要求出中垂線的方程,自己YY吧,不過我的做法可能比較傳統,然後還需要考慮斜率不存在的情況。

有了方程,還要注意不等式的正負,也就是地區的方向。

不斷地加上新的半平面,切割原有的凸多邊形。

注意:出現same的話,說明目標在中垂線上,而題目要求的是面積,所以答案為0.而且之後的所有輸出都應該為0.

當之前出現了面積為0的情況,說明之前一組就已經找不到可列區域了,之後的所有答案也應為0

POJ,ZOJ,FZU都有這題,資料也有些不同,可以都嘗試一下。

#include<iostream>#include<fstream>#include<iomanip>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<cmath>#include<set>#include<map>#include<queue>#include<stack>#include<string>#include<vector>#include<sstream>#include<cassert>#define LL long long#define eps 1e-8#define inf 10000#define zero(a) fabs(a)<eps#define N 20005using namespace std;struct Point{    double x,y;    Point(){}    Point(double tx,double ty){x=tx;y=ty;}}pre,cur,p[105],tp[105];double xmul(Point p0,Point p1,Point p2){    return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);}//給出兩點,算出中垂線的標準方程void Get_midperpendicular(Point p1,Point p2,double &a,double &b,double &c){    //中垂線斜率為0    if(zero(p1.x-p2.x)) a=0,b=1;    //中垂線斜率不存在    else if(zero(p1.y-p2.y)) a=1,b=0;    //一般情況    else b=p2.y-p1.y,a=p2.x-p1.x;    c=-a*(p2.x+p1.x)/2-b*(p2.y+p1.y)/2;}Point Get_Intersection(Point p1,Point p2,double a,double b,double c){    double u=fabs(a*p1.x+b*p1.y+c),v=fabs(a*p2.x+b*p2.y+c);    return Point((p1.x*v+p2.x*u)/(u+v),(p1.y*v+p2.y*u)/(u+v));}void Cut(double a,double b,double c,Point p[],int &cnt){    int tmp=0;    for(int i=1;i<=cnt;i++){        if(a*p[i].x+b*p[i].y+c>-eps) tp[++tmp]=p[i];        else{            if(a*p[i-1].x+b*p[i-1].y+c>eps)                tp[++tmp]=Get_Intersection(p[i-1],p[i],a,b,c);            if(a*p[i+1].x+b*p[i+1].y+c>eps)                tp[++tmp]=Get_Intersection(p[i+1],p[i],a,b,c);        }    }    for(int i=1;i<=tmp;i++)        p[i]=tp[i];    p[0]=tp[tmp];p[tmp+1]=p[1];    cnt=tmp;}double Get_Area(Point p[],int n){    double area=0;    for(int i=2;i<n;i++)        area+=xmul(p[1],p[i],p[i+1]);    return fabs(area)/2.0;}int main(){    pre.x=pre.y=0;    char str[10];    p[1].x=0;p[1].y=0;    p[2].x=0;p[2].y=10;    p[3].x=10;p[3].y=10;    p[4].x=10;p[4].y=0;    p[0]=p[4];p[5]=p[1];    int cnt=4;    double area=1.0;    while(scanf("%lf%lf%s",&cur.x,&cur.y,str)!=EOF){        double a,b,c;        Get_midperpendicular(pre,cur,a,b,c);        //確定不等式,使得地區範圍為ax+by+c>0        if(strcmp(str,"Colder")==0){            if(a*pre.x+b*pre.y+c<-eps){a=-a;b=-b;c=-c;}        }        else if(strcmp(str,"Hotter")==0){            if(a*cur.x+b*cur.y+c<-eps){a=-a;b=-b;c=-c;}        }        else            area=0;        //如果出現了same或者之前面積為0,之後都為0        if(zero(area)){            printf("0.00\n");            continue;        }        Cut(a,b,c,p,cnt);        area=Get_Area(p,cnt);        printf("%.2f\n",area);        pre=cur;    }    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.