CSU

来源:互联网 发布:sql中出现次数最多的 编辑:程序博客网 时间:2024/06/14 00:33

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1812

注意:点逆序 可以用半平面交 或者多边形面积交

半平面交(转至http://blog.csdn.net/a664607530/article/details/52434724)

#include <bits/stdc++.h>using namespace std;#define e exp(1.0); //2.718281828#define mod 1000000007#define inf 0x3f3f3f3ftypedef long long LL;#define INF 0x7fffffff#define zero(x) (((x)>0?(x):(-x))<eps)const double eps = 1e-8;const double pi = acos(-1.0);//判断数k的符号 -1负数 1正数 0零int dcmp(double k){    return k < -eps ? -1 : k > eps ? 1 : 0;}inline double sqr(double x){    return x * x;}struct point{    double x, y;    point(double a=0, double b=0): x(a), y(b) {};    void input()    {        scanf("%lf %lf", &x, &y);    }    friend point operator + (const point &a, const point &b)    {        return point(a.x + b.x, a.y + b.y);    }    friend point operator - (const point &a, const point &b)    {        return point(a.x - b.x, a.y - b.y);    }    friend bool operator == (const point &a, const point &b)    {        return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;    }    friend bool operator < (const point &a, const point &b)    {        return a.x < b.x || (a.x == b.x && a.y < b.y);    }    friend point operator * (const point &a, const double &b)    {        return point(a.x * b, a.y * b);    }    friend point operator * (const double &a, const point &b)    {        return point(a * b.x, a * b.y);    }    double norm()    {        return sqrt(sqr(x) + sqr(y));    }};//计算两个向量的叉积double cross(const point &a, const point &b){    return a.x * b.y - a.y * b.x;}double cross3(point A, point B, point C) //叉乘{    return (B.x - A.x) * (C.y - A.y) - (B.y - A.y) * (C.x - A.x);}//计算两个点的点积double dot(const point &a, const point &b){    return a.x * b.x + a.y * b.y;}double dot3(point A, point B, point C) //点乘{    return (C.x - A.x) * (B.x - A.x) + (C.y - A.y) * (B.y - A.y);}//求n边形的面积,多边形上的点要按逆时针的顺序存储在p中double ConvexPolygonArea(point *p, int n){    double area = 0;    for(int i = 1; i < n - 1; ++i)        area += cross(p[i] - p[0], p[i + 1] - p[0]);    return area / 2;}//typedef complex<double> point;//typedef pair<point,point> halfplane;struct halfplane{    point a, b;    halfplane() {};    halfplane(point a, point b): a(a), b(b) {};};inline double satisfy(point a, halfplane p){    return dcmp(cross(a - p.a, p.b - p.a)) <= 0;}point crosspoint(const halfplane &a, const halfplane &b){    double k = cross(b.a - b.b, a.a - b.b);    k = k / (k - cross(b.a - b.b, a.b - b.b));    return a.a + (a.b - a.a) * (k);}double arg(point p){    return arg(complex<double>(p.x, p.y));}bool cmp(const halfplane &a, const halfplane &b){    int res = dcmp(arg(a.b - a.a) - arg(b.b - b.a));    return res == 0 ? satisfy(a.a, b) : res < 0;}int halfplaneIntersection(halfplane *v, int n, point *out){    //sort(v.begin(),v.end(),cmp);    sort(v, v + n, cmp);    deque<halfplane> q;    deque<point> ans;    q.push_back(v[0]);    for(int i = 1; i < n; ++i)    {        if(dcmp(arg(v[i].b - v[i].a) - arg(v[i - 1].b - v[i - 1].a)) == 0)        {            continue;        }        while(ans.size() > 0 && !satisfy(ans.back(), v[i]))        {            ans.pop_back();            q.pop_back();        }        while(ans.size() > 0 && !satisfy(ans.front(), v[i]))        {            ans.pop_front();            q.pop_front();        }        ans.push_back(crosspoint(q.back(), v[i]));        q.push_back(v[i]);    }    while(ans.size() > 0 && !satisfy(ans.back(), q.front()))    {        ans.pop_back();        q.pop_back();    }    while(ans.size() > 0 && !satisfy(ans.front(), q.back()))    {        ans.pop_front();        q.pop_front();    }    ans.push_back(crosspoint(q.back(), q.front()));    int m = 0;    while(ans.empty() == false)    {        out[m++] = ans.front();        ans.pop_front();    }    return m;}halfplane v[222];point out[222];point a[222], b[222];int main(){    int n1, n2;    int cas = 0;    double x1, y1, x2, y2;    double x3, y3, x4, y4;    while(scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2) != EOF)    {        scanf("%lf %lf %lf %lf", &x3, &y3, &x4, &y4);        a[0] = point(x1, y1);        a[1] = point(x2, y1);        a[2] = point(x1, y2);        int n = 0;        if(x1 > x2 && y1 > y2)        {            v[n++] = halfplane(a[0], a[1]);            v[n++] = halfplane(a[1], a[2]);            v[n++] = halfplane(a[2], a[0]);        }        else if(x1 > x2 && y1 < y2)        {            v[n++] = halfplane(a[0], a[2]);            v[n++] = halfplane(a[2], a[1]);            v[n++] = halfplane(a[1], a[0]);        }        else if(x1 < x2 && y1 > y2)        {            v[n++] = halfplane(a[0], a[2]);            v[n++] = halfplane(a[2], a[1]);            v[n++] = halfplane(a[1], a[0]);        }        else if(x1 < x2 && y1 < y2)        {            v[n++] = halfplane(a[0], a[1]);            v[n++] = halfplane(a[1], a[2]);            v[n++] = halfplane(a[2], a[0]);        }        b[0] = point(x3, y3);        b[1] = point(x4, y3);        b[2] = point(x4, y4);        b[3] = point(x3, y4);        v[n++] = halfplane(b[0], b[1]);        v[n++] = halfplane(b[1], b[2]);        v[n++] = halfplane(b[2], b[3]);        v[n++] = halfplane(b[3], b[0]);        int m = halfplaneIntersection(v, n, out);        printf("%.8f\n", ConvexPolygonArea(out, m));    }    return 0;}
多边形面积交

#include<bits/stdc++.h>using namespace std;const int maxn = 555;const int maxisn = 10;const double eps = 1e-8;const double pi = acos(-1.0);int dcmp(double x){    if(x > eps) return 1;    return x < -eps ? -1 : 0;}inline double Sqr(double x){    return x * x;}struct Point{    double x, y;    Point(double x = 0, double y = 0): x(x), y(y) {};    friend Point operator + (const Point &a, const Point &b)    {        return Point(a.x + b.x, a.y + b.y);    }    friend Point operator - (const Point &a, const Point &b)    {        return Point(a.x - b.x, a.y - b.y);    }    friend bool operator == (const Point &a, const Point &b)    {        return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;    }    friend Point operator * (const Point &a, const double &b)    {        return Point(a.x * b, a.y * b);    }    friend Point operator * (const double &a, const Point &b)    {        return Point(a * b.x, a * b.y);    }    friend Point operator / (const Point &a, const double &b)    {        return Point(a.x / b, a.y / b);    }    friend bool operator < (const Point &a, const Point &b)    {        return a.x < b.x || (a.x == b.x && a.y < b.y);    }    inline double dot(const Point &b)const    {        return x * b.x + y * b.y;    }    inline double cross(const Point &b, const Point &c)const    {        return (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);    }};Point LineCross(const Point &a, const Point &b, const Point &c, const Point &d){    double u = a.cross(b, c), v = b.cross(a, d);    return Point((c.x * v + d.x * u) / (u + v), (c.y * v + d.y * u) / (u + v));}double PolygonArea(Point p[], int n){    if(n < 3) return 0.0;    double s = p[0].y * (p[n - 1].x - p[1].x);    p[n] = p[0];    for(int i = 1; i < n; i++)    {        s += p[i].y * (p[i - 1].x - p[i + 1].x);    }    return fabs(s * 0.5);}double CPIA(Point a[], Point b[], int na, int nb){    Point p[maxisn], temp[maxisn];    int i, j, tn, sflag, eflag;    a[na] = a[0], b[nb] = b[0];    memcpy(p, b, sizeof(Point) * (nb + 1));    for(i = 0; i < na && nb > 2; ++i)    {        sflag = dcmp(a[i].cross(a[i + 1], p[0]));        for(j = tn = 0; j < nb; ++j, sflag = eflag)        {            if(sflag >= 0) temp[tn++] = p[j];            eflag = dcmp(a[i].cross(a[i + 1], p[j + 1]));            if((sflag ^ eflag) == -2)                temp[tn++] = LineCross(a[i], a[i + 1], p[j], p[j + 1]);        }        memcpy(p, temp, sizeof(Point)*tn);        nb = tn, p[nb] = p[0];    }    if(nb < 3) return 0.0;    return PolygonArea(p, nb);}double SPIA(Point a[], Point b[], int na, int nb){    int i, j;    Point t1[4], t2[4];    double res = 0.0, if_clock_t1, if_clock_t2;    a[na] = t1[0] = a[0];    b[nb] = t2[0] = b[0];    for(i = 2; i < na; i++)    {        t1[1] = a[i - 1], t1[2] = a[i];        if_clock_t1 = dcmp(t1[0].cross(t1[1], t1[2]));        if(if_clock_t1 < 0) swap(t1[1], t1[2]);        for(j = 2; j < nb; j++)        {            t2[1] = b[j - 1], t2[2] = b[j];            if_clock_t2 = dcmp(t2[0].cross(t2[1], t2[2]));            if(if_clock_t2 < 0) swap(t2[1], t2[2]);            res += CPIA(t1, t2, 3, 3) * if_clock_t1 * if_clock_t2;        }    }    return res;}//多边形a、b的点的顺序需要按照逆时针排序Point a[10],b[10];int main(){    double x1, y1, x2, y2, x3, y3, x4, y4;    while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4) != EOF)    {        int n1=3,n2=4;        a[0].x=x1,a[0].y=y1;        a[1].x=x1,a[1].y=y2;        a[2].x=x2,a[2].y=y1;        b[0].x=x3,b[0].y=y3;        b[1].x=x3,b[1].y=y4;        b[2].x=x4,b[2].y=y4;        b[3].x=x4,b[3].y=y3;        double ans=fabs(SPIA(a,b,n1,n2));        printf("%.8lf\n",ans);    }    return 0;}


原创粉丝点击