NC243148. The Designer
描述
输入描述
第一行包含一个整数 ,表示测试用例的数量。
对于每个测试用例,第一行包含两个正整数和 ,即两个大圆的半径。假设这两个圆在内部相切。
第二行包含一个正整数 ,也就是老师要加的小圆圈数。
输出描述
对于每个测试用例:
一行中输出一个数字,表示小圆圈的总面积。精度误差小于。
示例1
输入:
2 5 4 1 4 5 1
输出:
3.14159 3.14159
C++(g++ 7.5.0) 解法, 执行用时: 237ms, 内存消耗: 484K, 提交时间: 2022-10-06 16:28:57
#include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define ld long double #define endl '\n' #define PP pair<pair<ll ,ll>, int > #define P pair<ll,ll> #include<unordered_map> #pragma warning(disable:4996) #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); using namespace std; const int N = 1e5 + 100; const int M = 1e6 + 100; #define double long double const double eps = 1e-8; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; const double pi = acosl(-1.0); struct Point { double x, y; Point() {} Point(double x, double y) :x(x), y(y) {} Point operator -(Point b) { return Point(x - b.x, y - b.y); } Point operator +(Point b) { return Point(x + b.x, y + b.y); } Point operator *(double k) { return Point(x * k, y * k); } Point operator /(double k) { return Point(x / k, y / k); } double operator *(Point b) { return x * b.x + y * b.y; } double operator ^(Point b) { return x * b.y - y * b.x; } double len2() { return x * x + y * y; } }; double dist(Point A, Point B) { return sqrt((A - B).len2()); } struct circle { Point p; double r; circle() {} circle(Point p, double r) :p(p), r(r) {} Point point(double a) { return Point(p.x + cos(a) * r, p.y + sin(a) * r); } }; //圆 c 关于 p 反演所得到的圆 double inverse(circle c, Point p, double R) { double OA = (p - c.p).len2(); return R * R * c.r / (OA - c.r * c.r); } void solve() { double rr = 10.0; double r1, r2; cin >> r1 >> r2; if (r1 < r2)swap(r1, r2); double x1 = (rr * rr) / (2.0 * r1); double x2 = (rr * rr) / (2.0 * r2); double x = (x1 + x2) / 2.0; double r = fabs(x1 - x2) / 2.0; int n; cin >> n; Point p(0, 0); Point c1(x, 0), c2(x, 0); double tempr = inverse(circle(c1, r), p, rr); double ans = tempr * tempr * pi; for (int i = 2;i <= n;i++) { if (i % 2 == 0) { c1.y += r * 2.0; tempr = inverse(circle(c1, r), p, rr); if (tempr * tempr * pi < (1e-12))break; ans += tempr * tempr * pi; } else { c2.y -= r * 2.0; tempr = inverse(circle(c2, r), p, rr); if (tempr * tempr * pi < (1e-12))break; ans += tempr * tempr * pi; } } cout << ans << endl; } int main() { IOS; int T = 1; cout << fixed << setprecision(5); cin >> T; while (T--)solve(); return 0; } //114514
C++(clang++ 11.0.1) 解法, 执行用时: 121ms, 内存消耗: 444K, 提交时间: 2022-09-30 00:28:44
#include <bits/stdc++.h> #include <cmath> using namespace std; int main() { int t; cin >> t; for(int i = 0; i < t; i++) { int r1, r2; cin >> r1 >> r2; int N; cin >> N; if(r1 > r2) { swap(r1, r2); } double result = 0.; if(r1 == r2) { cout << fixed << setprecision(5) << result << endl; continue; } double k1 = -1. / r2, k2 = 1. / r1, k3 = 1./ (r2 - r1); double k4 = k1 + k2 + k3; result += (r2 - r1) * (r2 - r1); N -= 1; while(N > 0) { double cur = 1. / k4 / k4; if(cur < 1e-13) { break; } if(N >= 2) { result += 2. * cur; N -= 2; } else { result += cur; N -= 1; } double k5 = 2 * (k1 + k2 + k4) - k3; k3 = k4; k4 = k5; } cout << fixed << setprecision(5) << result * M_PI << endl; } return 0; }