Skip to content

Commit

Permalink
solve G problem
Browse files Browse the repository at this point in the history
  • Loading branch information
zenyarn committed Oct 11, 2024
1 parent 8682bcf commit cbf5cbc
Showing 1 changed file with 183 additions and 0 deletions.
183 changes: 183 additions & 0 deletions G.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"16.97\n"
]
}
],
"source": [
"import math\n",
"\n",
"# 计算两点之间的欧几里得距离\n",
"def distance(p1, p2):\n",
" return math.sqrt((p2[0] - p1[0])**2 + (p2[1] - p1[1])**2 + (p2[2] - p1[2])**2)\n",
"\n",
"# 计算最短距离\n",
"def calculate_shortest_distance(A, B, C, R):\n",
" dAC = distance(A, C)\n",
" dBC = distance(B, C)\n",
" dAB = distance(A, B)\n",
" \n",
" # 如果A到C或B到C的距离小于等于球体半径,说明A或B在球体内\n",
" if dAC <= R or dBC <= R:\n",
" return -1 # 特殊情况处理(可以根据题意调整)\n",
" \n",
" # 如果AB的直线不穿过球体,直接返回欧几里得距离\n",
" return dAB\n",
"\n",
"# 读取输入\n",
"A = list(map(float, input().split()))\n",
"B = list(map(float, input().split()))\n",
"C = list(map(float, input().split()))\n",
"R = float(input())\n",
"\n",
"# 计算并输出最短距离,保留两位小数\n",
"result = calculate_shortest_distance(A, B, C, R)\n",
"print(f\"{result:.2f}\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"19.71\n"
]
}
],
"source": [
"import math\n",
"\n",
"def read_point():\n",
" return list(map(int, input().strip().split()))\n",
"\n",
"def distance(p1, p2):\n",
" return math.hypot(p1[0]-p2[0], p1[1]-p2[1])\n",
"\n",
"def distance_point_to_line(A, B, C):\n",
" # A, B, C are tuples (x, y)\n",
" cross = abs( (B[0]-A[0])*(A[1]-C[1]) - (B[1]-A[1])*(A[0]-C[0]) )\n",
" dist = cross / distance(A, B)\n",
" return dist\n",
"\n",
"def tangent_points(P, C, R):\n",
" # P and C are tuples (x, y)\n",
" dx = P[0] - C[0]\n",
" dy = P[1] - C[1]\n",
" dist = math.hypot(dx, dy)\n",
" if dist < R:\n",
" return [] # No tangent\n",
" elif dist == R:\n",
" return [P] # One tangent point (the point itself)\n",
" else:\n",
" angle_PC = math.atan2(dy, dx)\n",
" alpha = math.acos(R / dist)\n",
" t1 = angle_PC + alpha\n",
" t2 = angle_PC - alpha\n",
" tp1 = (C[0] + R * math.cos(t1), C[1] + R * math.sin(t1))\n",
" tp2 = (C[0] + R * math.cos(t2), C[1] + R * math.sin(t2))\n",
" return [tp1, tp2]\n",
"\n",
"def angle_between(C, P1, P2):\n",
" # C is center, P1 and P2 are points on circle\n",
" v1x = P1[0] - C[0]\n",
" v1y = P1[1] - C[1]\n",
" v2x = P2[0] - C[0]\n",
" v2y = P2[1] - C[1]\n",
" dot = v1x * v2x + v1y * v2y\n",
" mag1 = math.hypot(v1x, v1y)\n",
" mag2 = math.hypot(v2x, v2y)\n",
" if mag1 ==0 or mag2==0:\n",
" return 0\n",
" cos_theta = dot / (mag1 * mag2)\n",
" # Clamp due to floating point\n",
" cos_theta = max(min(cos_theta,1), -1)\n",
" theta = math.acos(cos_theta)\n",
" return theta\n",
"\n",
"def compute_path(A, B, C, R):\n",
" # A, B, C are tuples (x, y)\n",
" dist_AB = distance(A, B)\n",
" dist_to_line = distance_point_to_line(A, B, C)\n",
" if dist_to_line >= R:\n",
" return dist_AB\n",
" # Compute tangent points\n",
" tangents_A = tangent_points(A, C, R)\n",
" tangents_B = tangent_points(B, C, R)\n",
" if not tangents_A or not tangents_B:\n",
" # No possible path\n",
" return None\n",
" min_path = float('inf')\n",
" for ta in tangents_A:\n",
" for tb in tangents_B:\n",
" # Compute angles for arc\n",
" angle = angle_between(C, ta, tb)\n",
" # Two possible arcs, choose the smaller one\n",
" arc = min(angle, 2*math.pi - angle) * R\n",
" path = distance(A, ta) + arc + distance(B, tb)\n",
" if path < min_path:\n",
" min_path = path\n",
" return min_path\n",
"\n",
"def main():\n",
" # Read input\n",
" A3D = read_point()\n",
" B3D = read_point()\n",
" C3D = read_point()\n",
" R = int(input())\n",
" # Project to 2D (x and z)\n",
" A = (A3D[0], A3D[2])\n",
" B = (B3D[0], B3D[2])\n",
" C = (C3D[0], C3D[2])\n",
" path_length = compute_path(A, B, C, R)\n",
" if path_length is None:\n",
" print(\"No valid path\")\n",
" else:\n",
" print(\"{0:.2f}\".format(path_length))\n",
"\n",
"if __name__ == \"__main__\":\n",
" main()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit cbf5cbc

Please sign in to comment.