沈学姐是一个科幻小说爱好者,最近她读了《三体》,喜欢数学的学姐对三体问题产生了兴趣。当然,学姐并不想去算某颗行星的轨道。
她把整个三体星系简化为一个平面,三颗恒星的球心投影成平面上的三点,每颗恒星都有一个半径为r的圆形引力场(r由恒星自身属性决定)。学姐想知道,三颗恒星的引力场总面积是多少。
第一行为一个整数T,表示数据组数。
每组数据有三行输入:
每行有三个数x,y,r(保留两位小数),分别为该恒星中心坐标(x,y)和引力场半径r。
(|x|<=5,|y|<=5,0<=r<=5)
对于第i组数据,输出一行,形如“Case #i: ans”(不含引号)
其中,ans表示引力场总面积,保留整数部分(因为学姐不想太难)。
样例输入
2
0.00 0.00 1.00
0.00 2.00 1.00
2.00 0.00 1.00
0.00 0.00 5.00
1.00 1.00 2.22
2.00 0.00 1.00
样例输出
Case #1: 9
Case #2: 79
参考代码:
#encoding :utf-8
import math
"""
这是求两个圆相交部分面积的参考代码(c):https://blog.csdn.net/aaakkk_1996/article/details/81746858
double ang1=acos((r1*r1+d*d-r2*r2)/(2*r1*d));
double ang2=acos((r2*r2+d*d-r1*r1)/(2*r2*d));
return ang1*r1*r1 + ang2*r2*r2 - r1*d*sin(ang1);
"""
def judge(list1,list2): #judge函数用来判定两圆之间的关系
d = ((list1[0]-list2[0])**2+(list1[1]-list2[1])**2)**0.5
if d >= list1[2]+list2[2]: #此时两个圆相切或者相离
return 1
elif abs(list1[2]-list2[2])<d and d<list1[2]+list2[2]: #相交但不包含
return 0
elif abs(list1[2]-list2[2])>=d:
return -1 #其中一个圆包含另一个
#返回不相交时的面积
def noCoincideArea(list1,list2):
area = math.pi*(list1[2]*list1[2]+list2[2]*list2[2])
return round(area)
#返回相交时的面积
def coincideArea(list1,list2):
d = math.sqrt((list1[0] - list2[0]) ** 2 + (list1[1] - list2[1]) ** 2)
ang1 = math.acos(((list1[2]*list1[2]) + d**2 - (list2[2]*list2[2]))/(2*d*list1[2]))
ang2 = math.acos(((list2[2]) ** 2 + d ** 2 - (list1[2]) ** 2) / (2 * d * list2[2]))
theCoincide = ang1*list1[2]*list1[2]+ang2*list2[2]*list2[2]-list1[2]*d*math.sin(ang1)
area = (math.pi*(list1[2]*list1[2]+list2[2]*list2[2]))-theCoincide
return round(area)
#判断三个圆知否存在包含关系,存在则删除被包含的那个圆
def isInclude(List):
includeList = []
if judge(List[0],List[1]) == -1:
if min(List[0][2],List[1][2]) == List[0][2]:
includeList.append(0)
else:
includeList.append(1) #表示圆0包含圆1
if judge(List[0],List[2]) == -1:
if min(List[0][2],List[2][2]) == List[0][2]:
includeList.append(0)
else:
includeList.append(2) #表示圆0包含圆2
if judge(List[1],List[2]) == -1:
if min(List[1][2],List[2][2]) == List[1][2]:
includeList.append(1)
else:
includeList.append(2) #表示圆1包含圆2
#开始删除被包含的圆
if includeList:
includeList = list(set(includeList))
for i in sorted(includeList,reverse=True):
List.pop(i)
T = eval(input()) #表示共几组数据
sumList = []
for i in range(T):
data = []
sum = 0
for j in range(3): #输入三个点的坐标和半径
data.append(list(map(float,input().split())))
#判断三个圆之间是否存在包含关系
tempData = data[:]
isInclude(tempData)
if len(tempData) == 1:
sumList.append(round(math.pi*tempData[0][2]*tempData[0][2]))
elif len(tempData) == 2:
if judge(tempData[0], tempData[1]) == 1:
sumList.append(noCoincideArea(tempData[0], tempData[1]))
elif judge(tempData[0], tempData[1]) == 0: # 则表示两个圆有相交
sumList.append(coincideArea(tempData[0], tempData[1]))
else:
#包含关系,仅在排除不存在包含关系之后
for j in range(len(tempData)-1):
for k in range(j+1,len(tempData)):
if judge(data[i],data[k]) == 1:
sum+=noCoincideArea(data[i],data[k])
elif judge(data[i],data[k]) == 0: #则表示两个圆有相交
sum+=coincideArea(data[i],data[k])
sumList.append(round(sum/2))
print("Case #"+str(i+1)+": "+str(sumList[i]))