题目大意:
给出
n
个圆弧,求出它们的交点,如果有重合圆弧,输出
分析:
WA
了无数次,各种
WS
的细节,具体看代码吧。
AC code:
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#define mp make_pair
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define ONLINE_JUDGE
typedef 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;
}