传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6158

本题是一个计算几何题——四圆相切。

平面上的一对内切圆,半径分别为R和r。现在这一对内切圆之间,按照如图所示的方式依次放置N个相切的圆。求放置的这N个圆的面积之和。

在此,首先介绍一个定理:笛卡尔定理。Wiki: Descartes' theorem

平面上的四个圆,第i个圆的半径为r[i],曲率为κ[i](注:κ=r­-1)。若这四个圆中的每一对均构成外切,则其曲率满足约束:

$\left(\sum_{i=1}^4 \kappa _i\right)^2 = 2\cdot \sum_{i=1}^4 \kappa _i^2$

通过这个定理,可以得到以下情景相应的约束:

平面上的三个圆,第i个圆的半径为r[i],曲率为κ[i]。若这三个圆中的每一对均构成外切,且同时内切于一个半径为R,曲率为K的大圆,则其曲率同样满足以上的关系(注:此处大圆的曲率应取负值,即K=-R-1)。半径的约束式相应地写成:

$\left(\sum_{i=1}^3 \kappa _i -\frac{1}{R} \right)^2 = 2\left( \sum_{i=1}^3 \kappa _i^2+\frac{1}{R^2}\right)$

接下来,首先考虑上半侧的情况(下半侧与之对称)。设上半侧放置的第k个圆的曲率为c[k](约定放置于中间的圆的曲率为c[0]),则其与半径为r的圆、放置的第k-1个圆相外切,并同时内切于半径为R的圆。根据四圆相切的关系写出约束式:

$\left(\frac{1}{r}-\frac{1}{R} +c_k+c_{k-1}\right)^2 = 2\left(\frac{1}{r^2}+\frac{1}{R^2} +c_k^2+c_{k-1}^2\right)$

相应地考虑第k+1个圆,则有:

$\left(\frac{1}{r}-\frac{1}{R} +c_k+c_{k+1}\right)^2 = 2\left(\frac{1}{r^2}+\frac{1}{R^2} +c_k^2+c_{k+1}^2\right)$

两式相减,则有:

$(c_{k+1}-c_{k-1})\left( 2\frac{R-r}{Rr}+2c_k+c_{k+1}+c_{k-1}\right )=2(c_{k+1}+c_{k-1})(c_{k+1}-c_{k-1})\\\Rightarrow 2\frac{R-r}{Rr}+2c_k=c_{k+1}+c_{k-1}\Rightarrow (c_{k+1}-c_k)-(c_k-c_{k-1})=2\frac{R-r}{Rr}$

设d[k]=c[k]-c[k-1],则d[]是一个等差数列。为求得这个等差数列,首先需要求解首项。

c[0]是显然的,而c[1]则可以借助与R、r、c[0]的关系求解。

$c_0=\frac{1}{R-r}\\c_1=\frac{R^2+r^2-Rr}{Rr(R-r)}$

于是,d[]的通项公式:$d_k=(2k-1)\frac{R-r}{Rr},k=1,2,3,\cdots$

于是,c[]的通项公式:$c_k=\frac{1}{R-r}+\frac{R-r}{Rr}k^2,k=0,1,2,3,\cdots$

求解时注意精度控制。参考程序如下:

#include <bits/stdc++.h>
using namespace std; const double pi = acos(-);
const double eps = 1e-; int R, r;
double a, b; double get_curv(int k)
{
return a + b * k * k;
} int main(void)
{
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d%d%d", &R, &r, &n);
if (R == r) {
printf("%.5f\n", );
continue;
}
if (R < r) swap(R, r);
a = 1.0 / (R - r);
b = 1.0 * (R - r) / (R * r);
//Add first circle.
int rad = 1.0 / get_curv();
double ans = rad * rad;
//Add following circles.
for (int i = ; i <= n; i += ) {
double rad = 1.0 / get_curv(i / );
double ds = rad * rad;
if (ds < eps) break;
ans += ds * (i < n ? : );
}
printf("%.5f\n", ans * pi);
}
return ;
}

本题还有一种更为简单的解法,即通过笛卡尔定理与韦达定理进行迭代。参考程序如下:

#include <bits/stdc++.h>
using namespace std; const double pi = acos(-);
const double eps = 1e-; int R, r; int main(void)
{
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d%d%d", &R, &r, &n);
if (R == r) {
printf("%.5f\n", );
continue;
}
if (R < r) swap(R, r);
//Add first circle.
double ans = (R - r) * (R - r);
double k_1 = -1.0 / R;
double k_2 = 1.0 / r;
double k_3 = 1.0 / (R - r);
double k_4 = k_1 + k_2 + k_3;
//Add following circles.
for (int i = ; i <= n; i += ) {
double ds = 1.0 / (k_4 * k_4);
if (ds < eps) break;
ans += ds * (i < n ? : );
double k_5 = 2.0 * (k_1 + k_2 + k_4) - k_3;
k_3 = k_4;
k_4 = k_5;
}
printf("%.5f\n", ans * pi);
}
return ;
}

HDU - 6158 The Designer的更多相关文章

  1. hdu 6158 The Designer( 反演圆)

    The Designer Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  2. HDU 6158 笛卡尔定理+韦达定理

    The Designer Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  3. HDU 6158 笛卡尔定理 几何

    LINK 题意:一个大圆中内切两个圆,三个圆两两相切,再不断往上加新的相切圆,问加上的圆的面积和.具体切法看图 思路:笛卡尔定理: 若平面上四个半径为r1.r2.r3.r4的圆两两相切于不同点,则其半 ...

  4. 「HDU6158」 The Designer(圆的反演)

    题目链接多校8-1009 HDU - 6158 The Designer 题意 T(<=1200)组,如图在半径R1.R2相内切的圆的差集位置依次绘制1,2,3,到n号圆,求面积之和(n< ...

  5. hdu6158 The Designer

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6158 题目: The Designer Time Limit: 8000/4000 MS (J ...

  6. hdu 1010 深搜+剪枝

    深度搜索 剪枝 还不是很理解 贴上众神代码 //http://blog.csdn.net/vsooda/article/details/7884772#include<iostream> ...

  7. hdu 1284完全背包

    http://acm.hdu.edu.cn/showproblem.php?pid=1284 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的 ...

  8. hdu 1548 楼梯 bfs或最短路 dijkstra

    http://acm.hdu.edu.cn/showproblem.php?pid=1548 Online Judge Online Exercise Online Teaching Online C ...

  9. hdu多校1002 Balanced Sequence

    Balanced Sequence Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s) ...

随机推荐

  1. 私有CA和证书

    证书类型 证书授权机构的证书 服务器 用户证书 获取证书两种方法 使用证书授权机构: 生成签名请求(csr ) 将csr发送给CA 从CA处接收签名 自签名的证书: 自已签发自己的公钥 openSSL ...

  2. sshfs把远程主机的文件系统映射到本地的目录中(转载)

    转自:http://www.fwolf.com/blog/post/329 windows之外的世界比想像中要大得多呢,几乎天天都在用ssh,却到今天才知道有sshfs这个好东西,前几天还在为Zend ...

  3. AutoCAD2013 以上利用AccoreConsole+ c# NetApi 批量处理图纸

    AccoreConsole听起来有点拗口,其中文名可以叫做AutoCAD控制台或者无头AutoCAD.一句话概括,它是快速启动AutoCAD运行微环境,高效的处理图纸.你可以如同DOS命令行一样操作命 ...

  4. CSS实现居中的方式

    在介绍居中方式之前,简单介绍一下行内元素和块级元素. 行内元素 和其他元素都在同一行 高,行高及外边距和内边距部分可以改变 宽度只与内容有关 行内元素只能容纳文本或者其他行内元素 常用内联元素:a,i ...

  5. redis的持久化的原理介绍和实现

    redis提供了持久化功能——RDB和AOF.通俗的讲就是将内存中的数据写入硬盘中. RDB一定时间取存储文件,AOF默认每秒去存储历史命令,官方建议两种方式同时使用 一.RDB(Redis Data ...

  6. PWBI--Excel 数据源

    博客园地址: http://blog.sina.com.cn/s/blog_68c4467d0102w5cc.html http://www.cnblogs.com/asxinyu/p/Power_B ...

  7. Elasticsearch--更好的搜索_加权得分,脚本,同义词

    目录 Apache Lucene评分 Elasticsearch的脚本功能 脚本执行过程中可以使用的对象 使用自定义的脚本库 搜索不同语言的内容 使用加权影响得分 加权 function_score查 ...

  8. 08使用NanoPiM1Plus在Android4.4.2下接TF卡

    08使用NanoPiM1Plus在Android4.4.2下接TF卡 大文实验室/大文哥 壹捌陆捌零陆捌捌陆捌贰 21504965 AT qq.com 完成时间:2017/12/5 17:51 版本: ...

  9. ORACLE 字符串补零

    标准函数Lpad 可以实现左补零,但是如果多于需要长度,则会截断字符串.如下:-----------------------情况一:需要补零.       SELECT LPAD ('1234' , ...

  10. Selenium IDE的第一个测试用例——路漫长。。。

    一周时间过去了,断断续续学习selenium也有几个小时了:今天细想一下学习效率不高的原因在哪,总结出以下几点: 1.求“进”心切——总想一步到位,搭建好环境,开始动手写用例. 2.学习深度不够——同 ...