套一下模板就行了
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 1000005 #define maxm 2000005 #define eps 1e-10 #define mod 1000000007 #define INF 1e9 #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; //三态函数 int dcmp(double d) { if(fabs(d) < eps) return 0; else return d > eps ? 1 : -1; } struct point { double x, y; point(){} point(double x, double y) : x(x), y(y) {} bool operator < (const point& b) const { if(dcmp(x - b.x) == 0) return dcmp(y - b.y) < 0; else return x < b.x; } bool operator == (const point& b) const { return dcmp(x - b.x) == 0 && dcmp(y - b.y) == 0; } point operator + (const point& b) const { return point(x + b.x, y + b.y); } point operator - (const point& b) const { return point(x - b.x, y - b.y); } point operator * (double b) const { return point(x * b, y * b); } point operator / (double b) const { return point(x / b, y / b); } void out(void) { printf("x = %.3f y = %.3f\n", x, y); } }; typedef point vec; struct line { point p; vec v; double ang; line(){} line(point p, vec v) : p(p), v(v) {} bool operator < (const line& b) const { return ang < b.ang; } }; //点积 double dot(vec a, vec b) { return a.x * b.x + a.y * b.y; } //向量的长度 double length(vec a) { return sqrt(dot(a, a)); } //两个向量的夹角 double angle(vec a, vec b) { return acos(dot(a, b) / length(a) / length(b)); } //向量叉积 double cross(vec a, vec b) { return a.x * b.y - a.y * b.x; } //向量旋转,rad是弧度 vec rotate(vec a, double rad) { return vec(a.x * cos(rad) - a.y * sin(rad), a.x * sin(rad) + a.y * cos(rad)); } //求法向量,顺时针旋转90度 vec normal(vec a) { double L = length(a); return vec(-a.y / L, a.x / L); } //求两条直线的交点,调用前要确保两条直线相交 point intersection(point a, vec v1, point b, vec v2) { vec u = a - b; double t = cross(v2, u) / cross(v1, v2); return a + v1 * t; } //求两条直线的交点,调用前要确保两条直线相交 point intersection(line a, line b) { vec u = a.p - b.p; double t = cross(b.v, u) / cross(a.v, b.v); return a.p + a.v * t; } //求点到直线的距离 double distoline(point p, point a, point b) { vec v1 = b - a, v2 = p - a; return fabs(cross(v1, v2)) / length(v1); //如果不取绝对值得到的是有向距离 } //求点到线段的距离 double distosegment(point p, point a, point b) { if(a == b) return length(p - a); vec v1 = b - a, v2 = p - a, v3 = p - b; if(dcmp(dot(v1, v2)) < 0) return length(v2); else if(dcmp(dot(v1, v3)) > 0) return length(v3); else return fabs(cross(v1, v2)) / length(v1); } //点在线段上的投影 point projection(point p, point a, point b) { vec v = b - a; return a + v * (dot(v, p - a) / dot(v, v)); } //已经知道p在ab直线上,判断p和线段ab的关系 //p在不在线段上返回1,在线段端点返回0,在线段上返回-1 int onseg(point p, point a, point b) { if(fabs(a.x - b.x) > fabs(a.y - b.y)) return dcmp(p.x - a.x) * dcmp(p.x - b.x); else return dcmp(p.y - a.y) * dcmp(p.y - b.y); } //线段相交,规范相交返回1,不规范相交返回2,不相交返回0 bool segtoseg(point a1, point b1, point a2, point b2) { int d1 = dcmp(cross(b1 - a1, a2 - a1)); int d2 = dcmp(cross(b1 - a1, b2 - a1)); int d3 = dcmp(cross(b2 - a2, a1 - a2)); int d4 = dcmp(cross(b2 - a2, b1 - a2)); if(d1 * d2 < 0 && d3 * d4 < 0) return 1; if(d1 == 0 && onseg(a2, a1, b1) <= 0) return 2; if(d2 == 0 && onseg(b2, a1, b1) <= 0) return 2; if(d3 == 0 && onseg(a1, a2, b2) <= 0) return 2; if(d4 == 0 && onseg(b1, a2, b2) <= 0) return 2; return 0; } //多边形的有向面积数组下标从0开始 double polygonarea(point *p, int n) { double res = 0; for(int i = 1; i < n-1; i++) res += cross(p[i] - p[0], p[i+1] - p[0]); return res / 2; } //计算凸包,输入一定要保证没有重复点 int convex(point *p, int n, point *res) { sort(p, p+n); int m = 0; for(int i = 0; i < n; i++) { while(m > i && dcmp(cross(res[m-1] - res[m-2], p[i] - res[m-2])) <= 0) m--; //如果想在凸包上有输入点改成<,下面也要改 res[m++] = p[i]; } int k = m; for(int i = n-2; i >= 0; i--) { while(m > k && dcmp(cross(res[m-1] - res[m-2], p[i] - res[m-2])) <= 0) m--; res[m++] = p[i]; } if(n > 1) m--; return m; } //半平面交 bool onleft(line l, point p) { return cross(l.v, p - l.p) > 0; } point pp[maxn]; line qq[maxn]; int halfplane(line *l, int n, point *poly) { sort(l, l+n);//按极角排序,注意如果题目已经有序就不用排序 int f, r; qq[f = r = 0] = l[0]; for(int i = 1; i < n; i++) { while(f < r && !onleft(l[i], pp[r-1])) r--; while(f < r && !onleft(l[i], pp[f])) f++; qq[++r] = l[i]; if(dcmp(cross(qq[r].v, qq[r-1].v)) == 0) { r--; if(onleft(qq[r], l[i].p)) qq[r] = l[i]; } if(f < r) pp[r-1] = intersection(qq[r-1], qq[r]); } while(f < r && !onleft(qq[f], pp[r-1])) r--; if(r - f <= 1) return 0; pp[r] = intersection(qq[r], qq[f]); int m = 0; for(int i = f; i <= r; i++) poly[m++] = pp[i]; return m; } struct circle { point c; double r; circle() {} circle(point c, double r) : c(c), r(r) {} point topoint(double a) { return point(c.x + cos(a) * r, c.y + sin(a) * r); } }; //求直线和圆的交点,返回值是交点个数,sol课重复调用 int linetocircle(line l, circle c, double& t1, double& t2, vector<point>& sol) { double a = l.v.x, b = l.p.x - c.c.x; double cc = l.v.y, d = l.p.y - c.c.y; double e = a * a + cc * cc, f = 2 * (a * b + cc * d), g = b * b + d * d - c.r * c.r; double delta = f * f - 4 * e * g; if(dcmp(delta) < 0) return 0; if(dcmp(delta) == 0) { t1 = t2 = -f / (2 * e); sol.push_back(l.p + l.v * t1); return 1; } t1 = (-f - sqrt(delta)) / (2 * e); t2 = (-f + sqrt(delta)) / (2 * e); sol.push_back(l.p + l.v * t1); sol.push_back(l.p + l.v * t2); return 2; } //求极角 double angle(vec v) { return atan2(v.y, v.x); } //两圆相交返回交点个数,两圆重合返回-1 int cirtocir(circle c1, circle c2, vector<point>& sol) { double d = length(c1.c - c2.c); if(dcmp(d) == 0) { if(dcmp(c1.r - c2.r) == 0) return -1; return 0; } if(dcmp(c1.r + c2.r - d) < 0) return 0; if(dcmp(fabs(c1.r - c2.r) - d) > 0) return 0; double a = angle(c2.c - c1.c); double da = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d)); point p1 = c1.topoint(a - da), p2 = c1.topoint(a + da); sol.push_back(p1); if(p1 == p2) return 1; sol.push_back(p2); return 2; } point aa; circle c1, c2; vector<point> ans; void read(void) { scanf("%lf%lf", &aa.x, &aa.y); c1.c.x = c1.c.y = 0, c1.r = length(aa); c2.c.x = aa.x, c2.c.y = aa.y, c2.r = c1.r * sqrt(3); } void work(void) { ans.clear(); cirtocir(c1, c2, ans); point p1 = ans[0], p2 = ans[1]; if(fabs(p1.y - p2.y) < 0.0005) { if(dcmp(p1.x - p2.x) >= 0) swap(p1, p2); printf("%.3f %.3f %.3f %.3f\n", p1.x, p1.y, p2.x, p2.y); } else { if(dcmp(p1.y - p2.y) >= 0) swap(p1, p2); printf("%.3f %.3f %.3f %.3f\n", p1.x, p1.y, p2.x, p2.y); } } int main(void) { int _; while(scanf("%d", &_)!=EOF) { while(_--) { read(); work(); } } return 0; }