python:三体问题

it2025-09-18  4

题目描述

沈学姐是一个科幻小说爱好者,最近她读了《三体》,喜欢数学的学姐对三体问题产生了兴趣。当然,学姐并不想去算某颗行星的轨道。

她把整个三体星系简化为一个平面,三颗恒星的球心投影成平面上的三点,每颗恒星都有一个半径为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]))
最新回复(0)