列表

详情


NC243148. The Designer

描述

有一天,小哈从他的老师那得到了一个问题。他的老师想为学校设计一个其中有一些圆相切的大标志。而现在,问题来了。老师想在一个大平面上画出标志。您可以在Figure1中看到图的示例:

首先,小哈的老师给了他两个很大的圆,它们彼此相切。然后,他想在较小的圆圈之外的区域添加更多的小圆圈,其次,在更大的圆圈内(如果你仔细看Figure1,你可能更容易理解这一点),每个小圆圈都是按以下原则添加的:

*您应该按照Figure1的顺序添加小圆圈。
*每次添加一个小圆圈时,应确保它与其他圆圈(2 或 3 个圆圈)相切,如Figure1所示。

老师想知道他在创作他的杰作时会使用的颜料总量。小哈不知道如何回答这个问题,所以他来找你。老师会给你他想在图中添加的小圆圈的数量。你应该编写一个程序来计算所有小圆圈的总面积。

输入描述

第一行包含一个整数t ,表示测试用例的数量。

对于每个测试用例,第一行包含两个正整数R1R2 ,即两个大圆的半径。假设这两个圆在内部相切。

第二行包含一个正整数N ,也就是老师要加的小圆圈数。

输出描述

对于每个测试用例:
一行中输出一个数字,表示小圆圈的总面积。精度误差小于

示例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;
}

上一题