套一下模板就行了
#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;
}