sgu227:The art to the broad masses!(计算几何)

来源:互联网 发布:淘宝网商城女装牛仔裤 编辑:程序博客网 时间:2024/05/17 03:08

题目大意:
      给出n个圆弧,求出它们的交点,如果有重合圆弧,输出Infinity

分析:
      WA了无数次,各种WS的细节,具体看代码吧。

AC code:

#include <cstdio>#include <cmath>#include <iostream>#include <algorithm>#define mp make_pair#define debug(...) fprintf(stderr, __VA_ARGS__)#define ONLINE_JUDGEtypedef double DB;const int MAXN = 59;const DB pi = acos(-1.0);const DB eps = 1e-8;int n;struct pot{    DB x, y;    pot(DB x = 0, DB y = 0):x(x),y(y){}    void read(){std::cin >> x >> y;}    void print(){printf("%.3lf %.3lf\n", x, y);}}a[MAXN], b[MAXN], c[MAXN], o[MAXN];DB r[MAXN], r2[MAXN];int fl[MAXN];pot ans[MAXN*MAXN];int tot;DB sqr(DB x) {return x*x;}bool is_zero(DB k){    return k >= -eps && k <= eps;   }int sign(DB k) {    if(k < -eps) return -1;    else return k > eps;}bool operator < (const pot &a, const pot &b){    if(is_zero(a.x-b.x)) return a.y < b.y;    return a.x < b.x;}pot operator - (const pot &a, const pot &b){    return pot(a.x-b.x, a.y-b.y);}pot operator + (const pot &a, const pot &b){    return pot(a.x+b.x, a.y+b.y);}bool operator == (const pot &a, const pot &b){    return is_zero(a.x-b.x) && is_zero(a.y-b.y);}DB dis2(const pot &a, const pot &b){    return sqr(a.x-b.x)+sqr(a.y-b.y);}DB dis(const pot &a, const pot &b){    return sqrt(dis2(a, b));}DB cross(const pot &a, const pot &b){    return a.x*b.y-a.y*b.x;}void insert(const pot &p, const pot &q, const pot &r, int id){    DB x1 = p.x, y1 = p.y, x2 = q.x, y2 = q.y, x3 = r.x, y3 = r.y;    DB a, b, c, d, e, f, x, y;    a=2*(x2-x1), b=2*(y2-y1), c=x2*x2+y2*y2-x1*x1-y1*y1;    d=2*(x3-x2), e=2*(y3-y2), f=x3*x3+y3*y3-x2*x2-y2*y2;    x=(b*f-e*c)/(b*d-e*a), y=(d*c-a*f)/(b*d-e*a);    o[id] = pot(x, y), ::r2[id] = dis2(o[id], p), ::r[id] = sqrt(::r2[id]);}int inside(const pot &p, int i){    return sign(cross(a[i]-p, b[i]-p))*fl[i];}std::pair<pot,pot> get(const pot &p, DB r1, const pot &q, DB r2){    DB m1 = p.x, n1 = p.y, m2 = q.x, n2 = q.y;    pot ret1, ret2;    if(!is_zero(m1-m2))    {        DB t = (sqr(r1)-sqr(r2)-sqr(m1)+sqr(m2)-sqr(n1)+sqr(n2))/(2*(m2-m1)), k = -(n2-n1)/(m2-m1);        DB A = sqr(k)+1, B = 2*k*(t-m1)-2*n1, C = sqr(t-m1)+sqr(n1)-sqr(r1);        DB deita = std::max(0.0, sqr(B)-4*A*C);        DB y = (-B+sqrt(deita))/(2*A), x = t+k*y;        ret1 = pot(x, y);        y = (-B-sqrt(deita))/(2*A), x = t+k*y;        ret2 = pot(x, y);    }    else    {        if(n1 < n2) std::swap(m1, m2), std::swap(n1, n2), std::swap(r1, r2);        DB dy = n1-n2, ty = (sqr(r1)-sqr(r2)+sqr(dy))/(2*dy), tx = sqrt(sqr(r1)-sqr(ty));        ret1 = pot(m1-tx, n1-ty), ret2 = pot(m1+tx, n1-ty);    }    return std::mp(ret1, ret2);}int main(){    #ifndef ONLINE_JUDGE    freopen("sgu227.in", "r", stdin);    freopen("sgu227.out", "w", stdout);    #endif    std::ios::sync_with_stdio(0);    std::cin >> n;    for(int i = 0; i < n; ++i)    {        a[i].read(), b[i].read(), c[i].read();        insert(a[i], b[i], c[i], i);        fl[i] = sign(cross(a[i]-c[i], b[i]-c[i]));    }    for(int i = 0; i < n; ++i)        for(int j = i+1; j < n; ++j)        {            if(o[i] == o[j] && is_zero(r2[i]-r2[j]))            {                if((fl[i] == fl[j] && !inside(a[i], j) && !inside(b[i], j)) || inside(a[i], j) > 0 || inside(b[i], j) > 0 || inside(a[j], i) > 0 || inside(b[j], i) > 0)                {                    puts("Infinity");                    return 0;                }                if(!inside(a[i], j)) ans[tot++] = a[i];                if(!inside(b[i], j)) ans[tot++] = b[i];                continue;            }            DB dij2 = dis2(o[i], o[j]);            if(sign(dij2-sqr(r[i]+r[j])) > 0 || sign(dij2-sqr(r[i]-r[j])) < 0) continue;            std::pair<pot, pot> node = get(o[i], r[i], o[j], r[j]);            if(inside(node.first, i) >= 0 && inside(node.first, j) >= 0) ans[tot++] = node.first;            if(inside(node.second, i) >= 0 && inside(node.second, j) >= 0) ans[tot++] = node.second;        }    std::sort(ans, ans+tot);    tot = std::unique(ans, ans+tot)-ans;    std::cout << tot << std::endl;    for(int i = 0; i < tot; ++i)        ans[i].print();    #ifndef ONLINE_JUDGE    fclose(stdin);    fclose(stdout);    #endif    return 0;}
0 0
原创粉丝点击