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

来源:互联网 发布:颜色代码源码 编辑:程序博客网 时间:2024/05/21 20:03

 

题意:

有一个二维(0,0)到(10,10)的区域,一个人从(0,0)开始一次拜访区域内的点,去找一样东西(就在这个区域内),每次他到达一个新的点后,都会有一句话,来告诉你是离那个东西更近了(Hotter),还是更远了(Colder),或者距离不变(Same),然后让你算出,这时那个东西可能处在的位置的区域的面积

 

注意点:

 

1. 这题主要搞清楚半平面要取到的区域,还有中垂线自己YY。

小知识: 与直线ax+by+c=0垂直的直线方程为bx-ay+d = 0, 根据这个不用考虑斜率为0或不存在的问题,很方便。

2. same以后的值都为0;

其它 模板。

 

模板1:

View Code
#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;#define eps 1e-8#define inf 1<<29struct point{    double x, y;    point(){}    point(double xx, double yy): x(xx), y(yy) {}}p[110], tp[110], cur, pre;int n, m;void getline(point p1, point p2, double &a, double &b, double &c) //获得中垂线{    point p3 = point( (p1.x + p2.x)/2, (p1.y + p2.y)/2 );    a = p1.x - p2.x;    b = p1.y - p2.y;    c = - a * p3.x - b * p3.y;}point intersect(point p1, point p2, double a, double b, double c){    double u = fabs(a * p1.x + b * p1.y + c);    double v = fabs(a * p2.x + b * p2.y + c);    point ans;    ans.x = (v * p1.x + u * p2.x) / (u + v);    ans.y = (v * p1.y + u * p2.y) / (u + v);    return ans;}void cut(double a, double b, double c)//切割{    int i, tm = 0;    for(i = 1; i <= m; i++)    {        if(a * p[i].x + b * p[i].y + c > eps)            tp[++tm] = p[i];        else        {            if( a * p[i-1].x + b * p[i-1].y + c > eps)                tp[++tm] = intersect(p[i-1], p[i], a, b, c);            if( a * p[i+1].x + b * p[i+1].y + c > eps)                tp[++tm] = intersect(p[i], p[i+1], a, b, c);        }    }    for(i = 1; i <= tm; i++)        p[i] = tp[i];    p[0] = p[tm];    p[tm+1] = p[1];    m = tm;}double cal(int n, point *p) //多边形面积{    int i;    double s = 0;    p[n+1] = p[1];    for(i = 1; i <= n; i++)        s += p[i].x * p[i+1].y - p[i].y *p[i+1].x;    return fabs(s) / 2;}char str[11];int main(){    //freopen("int.txt", "r", stdin);    int i, j;    bool flag = 0;    double a, b, c;    pre = point(0, 0);    m = n = 4;    p[1] = point(0, 0);    p[2] = point(0, 10);    p[3] = point(10, 10);    p[4] = point(10, 0);    p[5] = p[1];    p[0] = p[4];    while( ~scanf("%lf%lf%s", &cur.x, &cur.y, str) )    {        getline(pre, cur, a, b, c);        if(str[0] == 'C')         {                if(a * pre.x + b * pre.y + c < -eps)            { a = -a; b = -b; c = -c; }        }        else if(str[0] == 'H')        {            if(a * cur.x + b * cur.y + c < -eps)            { a = -a; b = -b; c = -c; }        }        else flag = 1; //注意same以后,每次答案都为0;        if(flag) { puts("0.00"); continue; }        cut(a, b, c);        printf("%.2f\n", cal(m, p));            pre = cur;    }    return 0;}

模板2:

View Code
#include<stdio.h>#include<string.h>#include<math.h>#include<vector>#include<algorithm>using namespace std;#define eps 1e-8struct point{    double x, y;    bool mark;    point(){}    point(double xx, double yy): x(xx), y(yy), mark(1) {}}cur, pre;vector<point> p;point mid(point p1, point p2){    point ans;    ans.x = (p1.x + p2.x) / 2;    ans.y = (p1.y + p2.y) / 2;    return ans;}void getline(point p1, point p2, double &a, double &b, double &c){    point p3 = mid(p1, p2);    a = p1.x - p2.x;    b = p1.y - p2.y;    c = -a * p3.x - b * p3.y;}point intersect( point p1, point p2, double a, double b, double c){    double u = fabs( a * p1.x + b * p1.y + c );    double v = fabs( a * p2.x + b * p2.y + c );    point ans;    ans.x = (v * p1.x + u * p2.x) / (u + v);    ans.y = (v * p1.y + u * p2.y) / (u + v);    return ans;}void cut(double a, double b, double c){    int i;    point tp;    for(i = 0; i < p.size(); i++)    {        if(a * p[i].x + b * p[i].y + c > eps)            p[i].mark= 1;        else p[i].mark = 0;    }    p.push_back( p[0] );    for(i = 0; i < p.size() - 1; i++)        if( p[i].mark^p[i+1].mark == 1)        {            tp = intersect(p[i], p[i+1], a, b, c);            p.insert(p.begin()+i+1, tp);            i++;        }    p.pop_back();    for(i = 0; i < p.size(); i++)        if(p[i].mark == 0)            p.erase(p.begin()+i), i--;}double cal(){    p.push_back(p[0]);    double s = 0;    int i;    for(i = 0; i < p.size() - 1; i++)        s += p[i].x *p[i+1].y - p[i].y * p[i+1].x;    p.pop_back();    return fabs(s)/2;}char str[11];int main(){    //freopen("int.txt", "r", stdin);    int i, j;    bool flag = 0;    double a, b, c;    p.clear();    p.push_back( point (0, 0));    p.push_back( point (0, 10));    p.push_back( point (10, 10));    p.push_back( point (10, 0));    pre = point(0, 0);    while( scanf("%lf%lf%s", &cur.x, &cur.y, str) != EOF )    {        getline(pre, cur, a, b, c);        if(str[0] == 'C')         {            if(a * pre.x + b * pre.y + c < -eps)            { a = -a; b = -b; c = -c;}        }        else if(str[0] == 'H')        {            if(a * cur.x + b * cur.y + c < -eps)            { a = -a; b = -b; c = -c;}        }        else flag = 1;        if(flag) { printf("0.00\n"); continue; }        cut(a, b, c);        printf("%.2f\n", cal());        pre = cur;    }    return 0;}