POJ 3449 Geometric Shapes (多边形相交)

来源:互联网 发布:巫师3a卡优化 编辑:程序博客网 时间:2024/05/23 11:26

这题主要是给正方形对角线两个点求另外两个点:不用旋转什么的,可以由点之间的关系推得。比较好推,具体见代码。

剩下的思路比较简单,输入输出有点麻烦,尤其是 A and C 和 A, B, and C 这种的区别。。。

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#include <map>#include <vector>#include <set>#include <string>#include <math.h>#include <cstdio>#include <cstring>#include <cctype>using namespace std;const double eps = 1e-8;int sgn(double x){    if (fabs(x) < eps) return 0;    if (x < 0) return -1;    else return 1;}struct Point{    double x,y;    Point(){}    Point(double _x,double _y)    {        x = _x;y = _y;    }    //向量    Point operator -(const Point &b)const    {        return Point(x - b.x,y - b.y);    }    //叉积    double operator ^(const Point &b)const    {        return x*b.y - y*b.x;    }    //点积    double operator *(const Point &b)const    {        return x*b.x + y*b.y;    }    void input()    {        scanf("%lf%lf",&x,&y);    }};struct Line{    Point s,e;    Line(){}    Line(Point _s,Point _e)    {        s = _s;e = _e;    }    //两直线相交求交点    //第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交    //只有第一个值为2时,交点才有意义    pair<int,Point> operator &(const Line &b)const    {        Point res = s;        if (sgn((s-e)^(b.s-b.e)) == 0)        {            if(sgn((s-b.e)^(b.s-b.e)) == 0)                return make_pair(0,res);//重合            else return make_pair(1,res);//平行        }        double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));        res.x += (e.x-s.x)*t;        res.y += (e.y-s.y)*t;        return make_pair(2,res);    }};bool inter(Line l1,Line l2)//判断线段相交{    return    max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&    max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&    max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&    max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&    sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&    sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;}typedef struct Shape {    string name, type;    int pnum, snum;    Point pts[27];    Line segs[27];}Shape;Shape shape[32];Point getp(){    Point ret;    string str;    cin >> str;    ret.x = ret.y = 0;    int pos = 0;    double sign = 1;    if(str[pos+1] == '-') {        sign = -1;        pos++;    }    while (isdigit(str[++pos]))        ret.x = ret.x * 10 + double(str[pos] - '0');    ret.x *= sign;    sign = 1;    if(str[pos+1] == '-') {        sign = -1;        pos++;    }    while (isdigit(str[++pos]))        ret.y = ret.y * 10 + double(str[pos] - '0');    ret.y *= sign;    return ret;}bool cmp(Shape a, Shape b){    return a.name < b.name;}int main(){    int scnt = 0;    string str1, str2;    while (cin >> str1) {        Shape & curs = shape[scnt];        if (str1 == "-") {            sort(shape, shape+scnt, cmp);            for (int i = 0; i < scnt; i++) {                cout << shape[i].name;                int ccnt = 0;                string buf[100];                for (int j = 0; j < scnt; j++) {                    if (i == j) continue;                    bool cro = false;                    for (int i0 = 0; !cro && i0 < shape[i].snum; i0++) {                        for (int j0 = 0; j0 < shape[j].snum; j0++) {                            if (inter(shape[i].segs[i0], shape[j].segs[j0])) {                                cro = true;                                break;                            }                        }                    }                    if (cro)                        buf[ccnt++] = shape[j].name;                }                if (ccnt == 0)                    cout << " has no intersections" << endl;                else {                    cout << " intersects with ";                    for (int j = 0; j < ccnt; j++) {                        if (j == 0)                            cout << buf[j];                        else if (j == ccnt - 1) {                            if(ccnt != 2) cout << ",";                            cout << " and " << buf[j] << endl;                        }                        else                            cout << ", " << buf[j];                    }                    if (ccnt == 1)                        cout << endl;                }            }            scnt = 0;            cout << endl;            continue;        } else if (str1 == ".")            break;        else            cin >> str2;        curs.name = str1;        curs.type = str2;        if (curs.type == "square") {            Point p[4];            p[0] = getp(), p[2] = getp();            curs.pnum = curs.snum = 4;            double x0 = p[0].x, y0 = p[0].y;            double x2 = p[2].x, y2 = p[2].y;            double a = x0 + x2, b = y2 - y0, c = y0 +y2, d = x0 - x2;            p[1].x = (a + b) / 2.0, p[1].y = (c + d) / 2.0;            p[3].x = (a - b) / 2.0, p[3].y = (c - d) / 2.0;            for (int i = 0; i < 4; i++) {                curs.pts[i] = p[i];                curs.segs[i].s = p[i];                curs.segs[i].e = p[(i+1) % 4];            }        } else if (curs.type == "rectangle") {            Point p[4];            for(int i = 0; i < 3; i++) p[i] = getp();            p[3].x = p[2].x + p[0].x - p[1].x;            p[3].y = p[2].y + p[0].y - p[1].y;            curs.pnum = curs.snum = 4;            for (int i = 0; i < 4; i++) {                curs.pts[i] = p[i];                curs.segs[i].s = p[i];                curs.segs[i].e = p[(i+1) % 4];            }        } else if (curs.type == "line") {            curs.pnum = 2;            curs.snum = 1;            curs.segs[0].s = curs.pts[0] = getp();            curs.segs[0].e = curs.pts[1] = getp();        } else if (curs.type == "triangle") {            curs.pnum = curs.snum = 3;            for (int i = 0; i < 3; i++)                curs.segs[i].s = curs.segs[(i+2) % 3].e = curs.pts[i] = getp();        } else if (curs.type == "polygon") {            cin >> curs.pnum;            curs.snum = curs.pnum;            for (int i = 0; i < curs.pnum; i++)                curs.segs[i].s = curs.segs[(i+curs.pnum-1) % curs.pnum].e = curs.pts[i] = getp();        }        scnt++;    }    return 0;}


0 0
原创粉丝点击