当前位置: 首页 > news >正文

UVa 319 Pendulum

题目描述

考虑一个用绳子挂在墙壁钩子上的摆锤。当被推动时,这个摆锤会来回摆动。现在想象在摆锤绳子的路径上放置其他钩子。摆锤会绕过它们,甚至可能围绕它们打转。一般来说,它会遵循比之前复杂得多的路径。一段时间后,摆锤的运动将重复,摆锤将进入一个周期性轨道。需要计算摆锤完成一个周期所经过的距离。

更正式地说,我们在墙上放置一个笛卡尔坐标系。摆锤的绳子固定在原点(0,0)(0,0)(0,0)xxx轴指向右,yyy轴指向上。摆锤的绳子长度为rrr。摆锤从(−r,0)(-r, 0)(r,0)位置释放,开始向右摆动。此外,平面上还有nnn个额外的钩子,可能影响摆锤的路径。

理想假设:

  • 钩子和绳子的直径为零
  • 摆锤没有能量损失(如摩擦)
  • 摆锤永远不会碰到钩子,只有绳子会碰到
  • 绳子由某种未来材料制成,只在接触钩子处弯曲,其他地方保持刚性

由于重力作用,摆锤永远不会达到高于起始点的高度(即永远不会高于xxx轴)。它要么再次达到初始高度,要么无限地绕钩子旋转。

输入格式

输入文件包含多个测试用例。每个测试用例以一行包含整数nnn(钩子数量,1≤n<5001 \leq n < 5001n<500)和实数rrr(摆绳长度)开始。接下来的nnn行每行包含两个整数,表示对应钩子的xxxyyy坐标。

文件以r=0r = 0r=0的用例结束,该用例不处理。

输出格式

对于每个用例,输出一行Pendulum #1Pendulum #2等。然后输出一行,包含摆锤完成一个周期所经过的距离(不计算到达轨道起点所经过的距离),精确到小数点后两位。每个测试用例后输出一个空行。

样例输入

2 16.0 3 -4 -3 -4 1 18.0 5 -12 0 0

样例输出

Pendulum #1 Length of periodic orbit = 87.66 Pendulum #2 Length of periodic orbit = 31.42

题目分析

问题的本质

这是一个几何模拟问题。摆锤从左侧水平位置释放,在重力作用下向右摆动。绳子在遇到钩子时会弯曲,绳子的一部分会“缠绕”在钩子上,从而改变有效摆长。

关键物理原理:

  • 摆锤的势能守恒,因此它永远不会超过初始高度(y=0y = 0y=0
  • 绳子总是拉紧的
  • 当绳子碰到钩子时,钩子到摆锤之间的绳子保持直线,而钩子到悬挂点之间的绳子则“绕过”钩子

运动过程

摆锤从(−r,0)(-r, 0)(r,0)释放。在重力作用下,它向右下方运动,然后向上摆动。由于能量守恒,它将在yyy轴上的某个最高点停止(但不会超过y=0y = 0y=0)。如果过程中没有碰到任何钩子,它会在初始高度处停止,然后反向摆回,形成一个完整的周期。

当绳子碰到钩子时,钩子成为新的“支点”。此时,有效摆长变为从钩子到摆锤的距离。摆锤继续摆动,可能会碰到更多钩子。

轨道类型

最终,摆锤会进入两种可能的周期性轨道:

  1. 左右摆动:在xxx轴两侧来回摆动,最高点为y=0y = 0y=0
  2. 绕圈:完全围绕一个钩子旋转(类似于圆周运动)

模拟方法

由于钩子数量有限,摆锤的绳子每次只会缠绕在最“外侧”的钩子上。我们可以模拟摆锤的运动,每一步确定下一个被绳子接触的钩子,然后更新有效摆长和角度范围,直到进入周期性状态。


解题思路

步骤一:坐标系与初始条件

  • 悬挂点(主钩子):(0,0)(0,0)(0,0)
  • 初始位置:(−r,0)(-r, 0)(r,0)
  • 初始角度:θ=−π\theta = -\piθ=π(从负xxx轴方向开始)

步骤二:钩子筛选

只有满足以下条件的钩子才可能被绳子碰到:

  • 钩子在xxx轴下方或xxx轴上(y≤0y \le 0y0),因为摆锤永远不会高于xxx
  • 钩子到当前悬挂点的距离 ≤ 当前有效摆长

步骤三:确定下一个钩子

在当前位置,绳子从当前悬挂点OOO延伸到摆锤PPP。当摆锤摆动时,绳子会扫过一定的角度范围。下一个被绳子接触的钩子是在这个角度范围内最靠近绳子的那个。

具体来说,对于每个候选钩子HHH

  • 计算极角θH=atan2(Hy−Oy,Hx−Ox)\theta_H = \text{atan2}(H_y - O_y, H_x - O_x)θH=atan2(HyOy,HxOx)
  • 这个角度必须在当前扫过的角度范围内(从上次角度到本次角度)
  • 选择使绳子偏转最大的钩子(即角度变化最小的方向?实际上是选择最“靠右”的钩子)

步骤四:更新状态

当绳子碰到钩子HHH时:

  • OOOHHH的一段绳子被“固定”在钩子上
  • 新的悬挂点变为HHH
  • 新的有效摆长变为原摆长减去∣OH∣|OH|OH
  • 新的角度为从HHHPPP的方向角
  • 摆锤继续摆动

步骤五:终止条件

模拟终止条件:

  • 如果当前摆长大于或等于悬挂点到xxx轴的距离,摆锤可以到达xxx轴。此时,它会在xxx轴上反弹,形成左右摆动周期。轨道长度 =2×2 \times2×(从当前角度到xxx轴的弧长)
  • 如果当前摆长小于悬挂点到xxx轴的距离,摆锤无法到达xxx轴,它会绕悬挂点做圆周运动。轨道长度 =2π×2\pi \times2π×摆长

步骤六:轨道长度计算

在模拟过程中,累加每次摆锤摆过的弧长(弧长=摆长×∣Δθ∣弧长 = 摆长 \times |\Delta\theta|弧长=摆长×∣Δθ)。当到达xxx轴或进入圆周运动时,加上最后一段弧长,然后乘以222(因为左右摆动对称)得到完整周期的长度。


算法复杂度分析

时间复杂度

  • 最多有nnn个钩子
  • 每一步确定下一个钩子:O(n)O(n)O(n)
  • 最多O(n)O(n)O(n)步(每个钩子最多被缠绕一次)
  • 总复杂度:O(n2)O(n^2)O(n2)n<500n < 500n<500,完全可行

空间复杂度

  • 存储钩子坐标:O(n)O(n)O(n)
  • 总空间复杂度:O(n)O(n)O(n)

正确性证明

引理 1:摆锤的运动由绳子与钩子的接触点决定。每次接触后,绳子被“缩短”,摆锤绕新支点摆动。

证明:绳子总是拉紧的,当碰到钩子时,钩子成为新的支点。由于绳子不会打滑,钩子到摆锤之间的部分保持直线。□\square

引理 2:在摆锤摆动过程中,绳子每次只会碰到最“外侧”的钩子(即最靠近当前绳子方向的钩子)。

证明:如果存在多个可能的钩子,最外侧的钩子会首先被绳子碰到。□\square

引理 3:模拟会在有限步内终止,因为每次有效摆长严格减小,且钩子数量有限。

证明:每次缠绕都会使有效摆长减小(减去∣OH∣>0|OH| > 0OH>0),因此最多进行nnn步。□\square

引理 4:最终轨道要么是左右摆动(到达xxx轴),要么是圆周运动(无法到达xxx轴)。

证明:能量守恒决定了摆锤无法超过初始高度。如果有效摆长足够长,它可以回到y=0y = 0y=0;否则,它会在最低点以下摆动,形成圆周运动。□\square


参考代码

// Pendulum// UVa ID: 319// Verdict: Accepted// Submission Date: 2017-05-29// UVa Run Time: 0.000s//// 版权所有(C)2017,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constdoubleEPSILON=1e-7,PI=2.0*acos(0.0);structpoint{doublex,y;};// 计算两点间距离doublegetDist(constpoint&p1,constpoint&p2){returnsqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2));}// 叉积计算:向量 ab 和 ac 的叉积doublecp(constpoint&a,constpoint&b,constpoint&c){return(b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}intmain(intargc,char*argv[]){cin.tie(0),cout.tie(0),ios::sync_with_stdio(false);intn,cases=0;doublex1,y1,lengthOfString;while(cin>>n>>lengthOfString,lengthOfString>0.0){cout<<"Pendulum #"<<++cases<<'\n';// 钩子列表,原点(主钩子)始终在列表中vector<point>hooks;hooks.push_back(point{0.0,0.0});for(inti=0;i<n;i++){cin>>x1>>y1;// 忽略 y > 0 的钩子(摆锤无法到达)if(y1>0)continue;// 忽略距离超过摆长的钩子if(lengthOfString+EPSILON<sqrt(x1*x1+y1*y1))continue;hooks.push_back(point{x1,y1});}intlastHookIdx=0;// 当前悬挂点索引doublelastTheta=-PI;// 当前角度(从负 x 轴开始)doubleorbit=0.0;// 轨道长度while(true){intnextHookIdx=-1;// 当前摆长下,摆锤能到达的最右角度(与 x 轴交点)doublerightmostAngle=asin(fabs(hooks[lastHookIdx].y)/lengthOfString);// 寻找下一个被绳子碰到的钩子for(inti=0;i<hooks.size();i++){if(i==lastHookIdx)continue;doublecurrentDist=getDist(hooks[i],hooks[lastHookIdx]);if(lengthOfString+EPSILON<currentDist)continue;doubletheta=atan2(hooks[i].y-hooks[lastHookIdx].y,hooks[i].x-hooks[lastHookIdx].x);// 检查角度是否在当前摆动范围内if(theta-rightmostAngle>EPSILON||theta+EPSILON<lastTheta){if(fabs(hooks[lastHookIdx].y)<lengthOfString+EPSILON)continue;}// 选择最合适的钩子(使绳子偏转最大的)if(nextHookIdx==-1){nextHookIdx=i;}else{doubleCP=cp(hooks[lastHookIdx],hooks[nextHookIdx],hooks[i]);if(fabs(CP)<EPSILON){// 共线时,选择距离更近的doublelastDist=getDist(hooks[nextHookIdx],hooks[lastHookIdx]);if(lastDist+EPSILON<currentDist)nextHookIdx=i;}elseif(CP<0){nextHookIdx=i;}}}// 没有更多钩子,进入周期性轨道if(nextHookIdx==-1){if(lengthOfString<fabs(hooks[lastHookIdx].y)+EPSILON){// 无法到达 x 轴,做圆周运动orbit=2.0*PI*lengthOfString;}else{// 左右摆动orbit+=lengthOfString*(rightmostAngle-lastTheta);orbit*=2.0;}cout<<"Length of periodic orbit = ";cout<<fixed<<setprecision(2)<<orbit<<"\n\n";break;}// 累加弧长,更新状态doublenextTheta=atan2(hooks[nextHookIdx].y-hooks[lastHookIdx].y,hooks[nextHookIdx].x-hooks[lastHookIdx].x);orbit+=lengthOfString*fabs(nextTheta-lastTheta);lengthOfString-=getDist(hooks[nextHookIdx],hooks[lastHookIdx]);lastHookIdx=nextHookIdx;lastTheta=nextTheta;}}return0;}

总结

本题的核心在于:

  1. 几何模拟:每次找到下一个被绳子接触的钩子
  2. 状态更新:改变悬挂点和有效摆长
  3. 终止条件:根据是否到达xxx轴区分两种轨道类型

关键点回顾

知识点说明
悬挂点原点为主钩子
初始角度−π-\piπ(从负xxx轴)
钩子筛选y≤0y \le 0y0,距离 ≤ 摆长
下一个钩子使绳子偏转最大的钩子
弧长计算$l \times
轨道类型左右摆动 或 圆周运动

物理直觉

摆锤的运动路径是所有可能路径中能量最小的那条。绳子的弯曲发生在钩子处,而钩子的选择由几何约束决定。这种模拟方法虽然简单,但正确反映了系统的动力学行为。

http://www.jsqmd.com/news/904369/

相关文章:

  • 2026 彩屏智能开关哪家质量好:深度解析独家测评 - 思溯深度专栏
  • 【LeetCode 热题 100】盛最多水的容器
  • 开封本地黄金回收靠谱门店怎么选看这篇就够了 优选长悦 - 专业黄金回收
  • OpenClaw单工作空间多智能体系统构建:基于环境工程的85%上下文优化方案
  • MsgHelper:微信私域全链路管理工具,客服宝平替的技术选型分析
  • Ubuntu下Zabbix Proxy配置指南
  • Arm架构MPAM在SMMU中的实现与优化实践
  • CANoe测试效率翻倍:详解CPAL脚本中那些容易被忽略的IL控制函数
  • HC7703晨芯阳电流模PFM同步升压DC-DC转换芯片
  • Sora 2数据叙事革命(2024Q2实测报告):为什么92.7%的BI团队已弃用静态看板?
  • 2026 彩屏智能开关怎么选:权威攻略最新解读 - 思溯深度专栏
  • 2026 郑州黄金回收避坑指南:商家实测与资质检验全攻略 - 合扬奢侈品交易中心
  • 虚幻引擎5时代,Cascade粒子系统用户如何用官方插件一键迁移到Niagara?
  • STM32F0/F1 FLASH编程期间中断失效的深度剖析与RAM运行方案实战
  • VScode 需要安装的插件和修改的设置
  • 抖音GIF动图怎么去水印2026全场景免费工具与实操方法汇总 - 科技热点发布
  • 如何快速掌握气象数据处理与可视化:MetPy实用指南
  • 别再傻傻分不清了!用Excel和Python实战演示标准差、标准误和置信区间的区别
  • 第二个华为长鑫科技,第二算力巨头给员工发200亿
  • 小团队如何靠数据飞轮在巨头夹缝中突围
  • 2026黔江黄金回收冠军揭晓:永兴荣登榜首!全城免费上门,五大门店实测 - 奢佳美黄金珠宝
  • 保姆级教程:在Ubuntu 22.04上用virt-manager创建你的第一个KVM虚拟机(附常见错误排查)
  • 【网址带?utm_source=chatgpt.com 的原因】
  • Win11Debloat终极指南:3步彻底清理Windows系统,让电脑重获新生
  • Sora 2数学可视化实战手册(含黎曼度量张量动画生成、同调群动态演化、随机过程轨迹采样等5大稀缺案例)
  • 百度文库文档免费获取终极指南:技术原理与实战应用
  • Redisson 组件 + 支付业务场景落地对照表
  • 2026年贵阳广告制作与亮化工程服务商选型指南:门头招牌、发光字、UV打印一站式对标 - 年度推荐企业名录
  • 加固用碳纤维板厂商九维测评:谁在技术与性价比间平衡最优 - 传粉科技
  • 保姆级教程:在Windows 10上搞定PPOCRLabel离线部署(附常见报错解决方案)