Finding the Radius for an Inserted Circle 笛卡尔定理 - 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛

本文介绍了如何根据笛卡尔定理计算在已有三个相切圆的情况下,连续插入若干个相切小圆时,每个新插入圆的半径。在2017年ACM-ICPC亚洲区(南宁赛区)网络赛中,给出了具体的问题描述和输入输出格式,并要求在限制条件下计算第k个插入圆的半径Rk的整数部分。
摘要由CSDN通过智能技术生成

Three circles C_{a}CaC_{b}Cb, and C_{c}Cc, all with radius RR and tangent to each other, are located in two-dimensional space as shown in Figure 11. A smaller circle C_{1}C1 with radius R_{1}R1 (R_{1}<RR1<R) is then inserted into the blank area bounded by C_{a}CaC_{b}Cb, and C_{c}Cc so that C_{1}C1 is tangent to the three outer circles, C_{a}CaC_{b}Cb, and C_{c}Cc. Now, we keep inserting a number of smaller and smaller circles C_{k}\ (2 \leq k \leq N)Ck (2kN) with the corresponding radius R_{k}Rk into the blank area bounded by C_{a}CaC_{c}Cc and C_{k-1}Ck1 (2 \leq k \leq N)(2kN), so that every time when the insertion occurs, the inserted circle C_{k}Ck is always tangent to the three outer circles C_{a}CaC_{c}Cc and C_{k-1}Ck1, as shown in Figure 11

Figure 1.

(Left) Inserting a smaller circle C_{1}C1 into a blank area bounded by the circle C_{a}CaC_{b}Cb and C_{c}Cc.

(Right) An enlarged view of inserting a smaller and smaller circle C_{k}Ck into a blank area bounded by C_{a}CaC_{c}Cc and C_{k-1}Ck1 (2 \leq k \leq N2kN), so that the inserted circle C_{k}Ck is always tangent to the three outer circles, C_{a}CaC_{c}Cc, and C_{k-1}Ck1.

Now, given the parameters RR and kk, please write a program to calculate the value of R_{k}Rk, i.e., the radius of the k-thkth inserted circle. Please note that since the value of R_kRk may not be an integer, you only need to report the integer part of R_{k}Rk. For example, if you find that R_{k}Rk = 1259.89981259.8998 for some kk, then the answer you should report is 12591259.

Another example, if R_{k}Rk = 39.102939.1029 for some kk, then the answer you should report is 3939.

Assume that the total number of the inserted circles is no more than 1010, i.e., N \leq 10N10. Furthermore, you may assume \pi = 3.14159π=3.14159. The range of each parameter is as below:

1 \leq k \leq N1kN, and 10^{4} \leq R \leq 10^{7}104R107.

Input Format

Contains l + 3l+3 lines.

Line 11ll ----------------- the number of test cases, ll is an integer.

Line 22RR ---------------- RR is a an integer followed by a decimal point,then followed by a digit.

Line 33kk ---------------- test case #11kk is an integer.

\ldots

Line i+2i+2kk ----------------- test case # ii.

\ldots

Line l +2l+2kk ------------ test case #ll.

Line l + 3l+3-11 ---------- a constant -11 representing the end of the input file.

Output Format

Contains ll lines.

Line 11kk R_{k}Rk ----------------output for the value of kk and R_{k}Rk at the test case #11, each of which should be separated by a blank.

\ldots

Line iikk R_{k}Rk ----------------output for kk and the value of R_{k}Rk at the test case # ii, each of which should be separated by a blank.

Line llkk R_{k}Rk ----------------output for kk and the value ofR_{k}Rk at the test case # ll, each of which should be separated by a blank.

样例输入
1
152973.6
1
-1
样例输出
1 23665
题目来源

2017 ACM-ICPC 亚洲区(南宁赛区)网络赛



题目如图所示,给出开始时圆的半径,求构造出的第k个圆的半径。


笛卡尔定理如下:

定义一个圆的曲率 k=±1r ,其中 r 是其半径。 
若平面有两两相切,且有 6 个独立切点的四个圆,设其曲率为 k1,k2,k3,k4 (若该圆与其他圆均外切,则曲率取正,否则取负)则其满足性质: 

(k1+k2+k3+k4)2=2(k21+k22+k23+k24)

接着,套公式算就可以了。


#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=100005, inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const ld pi = 3.14159L;
ld ans[15];

int main() {
	int cnt = 0,sum=0;
	ld l = 0L,r;
	int cas,s,i,k;
	scanf("%d", &cas);
		cin >> r;
		l = 1.0L / r ;
		r = l;
		for (i = 1; i <= 10; i++) {
			ans[i] = sqrt(2.0L*((r+r+l)*(r+r+l)-r*r-r*r - l*l));
			ans[i] += r + r + l;
		//	cout << ans[i] << endl;
			l = ans[i];
			ans[i] = 1.0L / ans[i];
		}
		while (cas--) {
			scanf("%d", &k);
			s = floor(ans[k]);
			printf("%d ", k);
			cout << s << endl;
		}
//		system("pause");
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值