难点只有第三问。算出夹角余弦值,然后换算出夹角正弦值,按虚数乘法旋转半径向量即可。
#include <cfloat>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <tuple>
using namespace std;
using ll = long long;
struct Point {
ll x;
ll y;
void Input() {
cin >> x >> y;
}
ll Len2() const {
return x * x + y * y;
}
};
struct PointD {
double x;
double y;
PointD() = default;
PointD(double x, double y): x(x), y(y) {}
PointD(const Point& other): x(other.x), y(other.y) {}
double Len2() const {
return x * x + y * y;
}
double Len() const {
return sqrt(Len2());
}
void RotateCoSi(double co, double si) {
tie(x, y) = make_tuple(x * co - y * si, y * co + x * si);
}
};
PointD operator+(const PointD& a, const PointD& b) {
return {a.x + b.x, a.y + b.y};
}
Point operator+(const Point& a, const Point& b) {
return {a.x + b.x, a.y + b.y};
}
Point operator-(const Point& a, const Point& b) {
return {a.x - b.x, a.y - b.y};
}
PointD operator*(const PointD& a, double b) {
return {a.x * b, a.y * b};
}
PointD operator/(const PointD& a, double b) {
return {a.x / b, a.y / b};
}
ll Cha(const Point& a, const Point& b) {
return a.x * b.y - a.y * b.x;
}
ll Dian(const Point& a, const Point& b) {
return a.x * b.x + a.y * b.y;
}
ll Dis2(const Point& a, const Point& b) {
return (b - a).Len2();
}
Point O;
ll r;
ll r2;
Point A;
void Solve() {
O.Input();
cin >> r;
A.Input();
r2 = r * r;
ll dis = Dis2(O, A);
if (dis < r2) {
cout << "1\n";
return;
}
if (dis == r2) {
cout << "2\n";
return;
}
double co = r / sqrt(dis);
double si = sqrt(1 - co * co);
PointD H1 = (A - O) * co;
PointD H2 = H1;
H1.RotateCoSi(co, si);
H2.RotateCoSi(co, -si);
H1 = O + H1;
H2 = O + H2;
// cout << co << endl;
cout << "3 " << H1.x << ' ' << H1.y << ' ' << H2.x << ' ' << H2.y << '\n';
}
int main() {
ios::sync_with_stdio(false);
cout << setprecision(DBL_DIG);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
Solve();
}
}
// 64 位输出请用 printf("%lld")

京公网安备 11010502036488号