poj 2540 求半平面交

来源:互联网 发布:刺客列传网络剧 编辑:程序博客网 时间:2024/05/24 03:32

题意 : 给你n 个点和一个标志,告诉你离这个点远了还是近了,让你求出那个点的可能位置。

题解 : 不难发现其实每一个点对应这一条垂直平分线然后看看这个区域有多大就可以了。

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cmath>#include <string>using namespace std;const double eps = 1e-8;const double inf = 10;const int maxn = 1505;struct Point{    double x,y;}p[maxn],tp[maxn],q[maxn];struct Node{    double x,y;    string s;}z[maxn];double ab (double x) {return x > 0 ? x : -x;}int sgn (double x) {    if (ab (x) < eps) return 0;    return x > 0 ? 1 : -1;}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);}Point Intersection(Point p1,Point p2,double a,double b,double c){    double u = ab(a*p1.x+b*p1.y+c);    double v = ab(a*p2.x+b*p2.y+c);    Point t;    t.x=(p1.x*v+p2.x*u)/(u+v);t.y=(p1.y*v+p2.y*u)/(u+v);    return t;}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 ab (-area/2.0);}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]=Intersection(p[i-1],p[i],a,b,c);            if(a*p[i+1].x+b*p[i+1].y+c>eps)                tp[++tmp]=Intersection(p[i],p[i+1],a,b,c);        }    }    for(int i=1;i<=tmp;i++)        p[i]=tp[i];    p[0]=p[tmp];p[tmp+1]=p[1];    cnt=tmp;}void solve(int n) {    p[1].x=0;p[1].y=0;    p[2].x=0;p[2].y=inf;    p[3].x=inf;p[3].y=inf;    p[4].x=inf;p[4].y=0;    p[0]=p[4];p[5]=p[1];    int cnt=4;    for(int i = 1;i < n;i++){        double a,b,c;        double ky = z[i].y - z[i - 1].y;        double kx = z[i].x - z[i - 1].x;        int f1 = sgn(z[i].x - z[i - 1].x);        int f2 = sgn(z[i].y - z[i - 1].y);        double midx = (z[i].x + z[i - 1].x ) / 2;        double midy = (z[i].y + z[i - 1].y) / 2;        if (z[i].s[0] == 'S') {            for (int j = i;j < n; ++j) cout << "0.00" <<endl;            break;        }        if (f2 == 0) {            b = 0;            a = 1;            c = -midx;        }        else if (f1 == 0) {            b = 1;            a = 0;            c = -midy;        }        else {            a = 1;            b = ky / kx;            c = -a * midx - b * midy;        }        if (z[i].s[0] == 'C') {            if (a * z[i].x + b * z[i].y + c > 0) {                a *= -1;                b *= -1;                c *= -1;            }        }        else {            if (a * z[i].x + b * z[i].y + c < 0) {                a *= -1;                b *= -1;                c *= -1;            }        }       // cout <<a <<' ' <<b <<' ' <<c << endl;        Cut(a,b,c,p,cnt);        //cout << cnt  << endl;        printf ("%.2f\n",Get_area(p, cnt));    }}int main(){   // freopen ("test.in","r",stdin);    //freopen ("test.out","w",stdout);    int n = 0;    z[0].x = 0.0,z[0].y = 0.0;    n ++;    while (cin >> z[n].x >> z[n].y >> z[n].s) {        n ++;    }    solve (n);    return 0;}
原创粉丝点击