NSWOJ-ZLH找女朋友E(圆内接正多边形)

题目描述

ZLH同学终于开始找女朋友啦,ZLH相中了一个会打红色警戒的妹子,妹子比较菜,每次都喜欢把建筑物建的特别集中,为了简化这个问题,我们认为妹子把他的建筑物建成了一个圆形,半径为R,现在,妹子希望建一些防御塔,保证敌方无论从哪个方向,都会在进入这个圆内部之前被防御塔打死,防御塔的防御半径为r,现在妹子希望省些钱以造坦克,ZLH一看有机会,就想写个程序计算至少需要几个防御塔以讨妹子欢心,但是他要撩妹,这个重任就交给你了

输入

输入的第一行为一个数字T,代表有T组测试数据(T<100)

 

接下来每行两个整数代表R和r(0<R,r<100000000)

输出

输出包含一行,代表至少需要多少个防御塔

样例输入

2
3 3
2 1

样例输出

1
6

分析:本题题意即用多个相同的圆构造出构成一个圆环包围一个大圆,求最少需要多少个圆,当所有小圆的圆心都在大圆的圆弧上且圆与圆之间两两相外切时所需要的小圆最少。如图

                              NSWOJ-ZLH找女朋友E(圆内接正多边形)

我们可以发现由样例2数据画出的图形中,多个圆构成的线两两相连最终构成了一个正多边形,而这个正多边形又是由六个全等的等腰三角形构成的,不难发现小圆数量与等腰三角形数量是始终相等的,那么我们可以求出一个等腰三角形的顶角来确定一个正多边形由多少个等腰三角形构成。也就同时能确定有多少个圆。由圆的性质我们可以如图看出其中有一个夹角为直角,又知道R和我们可以利用已知条件求出角1的正弦值再利用一下反三角函数求出角1的度数再乘2,即求出了一个等腰三角形的顶角,再用360度除以这个角度即算出了有多少个圆。如果结果是小数,那么还要+1补充一个圆。输出时向下取整即可。

不过当小圆半径大于等于大圆半径时,小圆是可以把大圆包住的,这时输出1即可。

#include<stdio.h>
#include<math.h>
#include<iostream>
#include<iomanip>
using namespace std;
double angle,a,b,c;
const double PI=3.1415926535;
int t;
int main()
{
	scanf("%d",&t);//输入测试数据数量
	while(t--)
	{
		scanf("%lf%lf",&a,&b);//输入大圆和小圆的半径
		if(a==b||a<b)
		{
			printf("1\n");continue;//如果小圆能够把大圆包住,输出1即可
		}
		angle=2*(asin(b/a)*180/PI);//计算等腰三角形顶角度数
		angle=360/angle;//计算三角形数量
		c=(int)angle;//
		if(angle!=c&&angle-c!=1)//当三角形数量为小数时,加一
			angle+=1;
		angle=(int)angle;//输出时改为整形向下取整
		cout<<fixed<<setprecision(0)<<angle<<endl;
	}
}