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

UVa 1398 Meteor

题目描述

著名的韩国互联网公司 NHN\texttt{NHN}NHN 提供了一项基于互联网的照片服务,用户可以通过控制 NHN\texttt{NHN}NHN 拥有的高性能望远镜直接拍摄太空中的天文现象。几天后,将出现一场被认为是本世纪最大的流星雨。NHN\texttt{NHN}NHN 宣布举办一场摄影比赛,奖励使用 NHN\texttt{NHN}NHN 照片服务拍摄到包含最多流星照片的用户。为了这次比赛,NHN\texttt{NHN}NHN 提前在其网页上提供了流星的轨迹信息。获胜的最佳方法是计算望远镜能够捕捉到最多流星的时刻。

你有 nnn 颗流星,每颗都做匀速直线运动。流星 mim_imi 随时间 ttt 沿轨迹 pi+t×vip_i + t \times v_ipi+t×vi 运动,其中 ttt 是非负实数值,pip_ipimim_imi 的起点,viv_ivimim_imi 的速度。点 pi=(xi,yi)p_i = (x_i, y_i)pi=(xi,yi)(X,Y)(X, Y)(X,Y) 平面中用 XXX 坐标 xix_ixiYYY 坐标 yiy_iyi 表示,速度 vi=(ai,bi)v_i = (a_i, b_i)vi=(ai,bi) 是一个非零向量,在 (X,Y)(X, Y)(X,Y) 平面中有两个分量 aia_iaibib_ibi

望远镜有一个矩形框架,左下角为 (0,0)(0, 0)(0,0),右上角为 (w,h)(w, h)(w,h)。当流星位于框架内部(不在边界上)时,称该流星在望远镜框架中。你需要计算望远镜框架中流星数量最多的某个时间,并输出该最大流星数量。

输入格式

输入包含 TTT 个测试用例。第一行给出测试用例的数量 TTT。每个测试用例的第一行包含两个整数 wwwhhh1≤w,h≤100,0001 \leq w, h \leq 100,0001w,h100,000),表示望远镜框架的宽度和高度,用一个空格分隔。第二行包含一个整数 nnn,表示输入点(流星)的数量,1≤n≤100,0001 \leq n \leq 100,0001n100,000。接下来的 nnn 行每行包含四个整数 xix_ixi, yiy_iyi, aia_iai, bib_ibi(xi,yi)(x_i, y_i)(xi,yi) 是起点 pip_ipi(ai,bi)(a_i, b_i)(ai,bi) 是第 iii 颗流星的非零速度向量 viv_ivixix_ixiyiy_iyi 是介于 −200,000-200,000200,000200,000200,000200,000 之间的整数值,aia_iaibib_ibi 是介于 −10-1010101010 之间的整数值。注意 aia_iaibib_ibi 中至少有一个不为零。这四个值用一个空格分隔。假设所有起点 pip_ipi 都是不同的。

输出格式

对于每个测试用例,输出望远镜框架中在某个时刻能够出现的流星的最大数量。

解题思路

问题分析

我们需要找到一个非负时间 ttt,使得在矩形 (0,0)(0,0)(0,0)(w,h)(w,h)(w,h) 内部(不含边界)的流星数量最多。每颗流星做匀速直线运动,运动方程为:

(x,y)=(xi,yi)+t⋅(ai,bi),t≥0(x, y) = (x_i, y_i) + t \cdot (a_i, b_i), \quad t \ge 0(x,y)=(xi,yi)+t(ai,bi),t0

关键思路

  1. 时间区间计算:对于每颗流星,我们可以计算出它进入矩形内部的时间区间 [tstart,tend)[t_{\text{start}}, t_{\text{end}})[tstart,tend)。如果流星从不进入矩形内部,则该区间为空。

  2. 边界条件处理:由于边界不算内部,我们需要使用严格不等式来处理进入和离开的时刻。

  3. 扫描线算法:将所有进入事件 (t,+1)(t, +1)(t,+1) 和离开事件 (t,−1)(t, -1)(t,1) 按时间排序,然后扫描这些事件,维护当前在矩形内部的流星数量,并记录最大值。

详细解题步骤

1. 计算单颗流星在矩形内部的时间区间

对于每颗流星,我们需要分别计算在 XXX 方向和 YYY 方向上的时间区间,然后取交集。

XXX 方向的时间区间

  • 如果 ai=0a_i = 0ai=0

    • 如果 xi≤0x_i \le 0xi0xi≥wx_i \ge wxiw:永远不在内部,区间为空
    • 否则:始终在内部,区间为 [0,∞)[0, \infty)[0,)
  • 如果 ai>0a_i > 0ai>0

    • 进入内部时间:当 xi+t⋅ai>0x_i + t \cdot a_i > 0xi+tai>0,即 t>−xiait > \frac{-x_i}{a_i}t>aixi
    • 离开内部时间:当 xi+t⋅ai<wx_i + t \cdot a_i < wxi+tai<w,即 t<w−xiait < \frac{w - x_i}{a_i}t<aiwxi
    • 因此区间为:(−xiai,w−xiai)\left( \frac{-x_i}{a_i}, \frac{w - x_i}{a_i} \right)(aixi,aiwxi)
  • 如果 ai<0a_i < 0ai<0

    • 进入内部时间:当 xi+t⋅ai<wx_i + t \cdot a_i < wxi+tai<w,即 t>w−xiait > \frac{w - x_i}{a_i}t>aiwxi(注意 ai<0a_i < 0ai<0
    • 离开内部时间:当 xi+t⋅ai>0x_i + t \cdot a_i > 0xi+tai>0,即 t<−xiait < \frac{-x_i}{a_i}t<aixi
    • 因此区间为:(w−xiai,−xiai)\left( \frac{w - x_i}{a_i}, \frac{-x_i}{a_i} \right)(aiwxi,aixi)

YYY 方向的时间区间(同理):

  • 如果 bi=0b_i = 0bi=0

    • 如果 yi≤0y_i \le 0yi0yi≥hy_i \ge hyih:永远不在内部,区间为空
    • 否则:始终在内部,区间为 [0,∞)[0, \infty)[0,)
  • 如果 bi>0b_i > 0bi>0

    • 区间为:(−yibi,h−yibi)\left( \frac{-y_i}{b_i}, \frac{h - y_i}{b_i} \right)(biyi,bihyi)
  • 如果 bi<0b_i < 0bi<0

    • 区间为:(h−yibi,−yibi)\left( \frac{h - y_i}{b_i}, \frac{-y_i}{b_i} \right)(bihyi,biyi)
2. 处理时间区间

对于每颗流星:

  • 计算 XXX 方向区间 [tx1,tx2)[t_{x1}, t_{x2})[tx1,tx2)
  • 计算 YYY 方向区间 [ty1,ty2)[t_{y1}, t_{y2})[ty1,ty2)
  • 取交集得到总区间 [max⁡(tx1,ty1),min⁡(tx2,ty2))[\max(t_{x1}, t_{y1}), \min(t_{x2}, t_{y2}))[max(tx1,ty1),min(tx2,ty2))
  • 如果开始时间小于 000,则设为 000(因为 t≥0t \ge 0t0
  • 如果区间有效(开始时间小于结束时间),则创建两个事件:
    • 进入事件:(tstart,+1)(t_{\text{start}}, +1)(tstart,+1)
    • 离开事件:(tend,−1)(t_{\text{end}}, -1)(tend,1)
3. 扫描线算法
  • 将所有事件按时间排序
  • 时间相同时,离开事件优先处理(避免多计数)
  • 扫描事件,维护当前流星数量,记录最大值

精度处理

由于输入是整数,使用 double\texttt{double}double 类型计算足够精确。使用一个小的 ϵ\epsilonϵ 值(如 10−910^{-9}109)来处理浮点精度问题。

参考代码

// Meteor
// UVa ID: 1398
// Verdict: Accepted
// Submission Date: 2025-11-01
// UVa Run Time: 0.030s
//
// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include <bits/stdc++.h>
using namespace std;const double EPS = 1e-9; // 精度控制// 事件结构体
struct Event {double time; // 事件发生时间int type;    // 事件类型:+1 表示进入,-1 表示离开Event(double t, int tp) : time(t), type(tp) {}// 排序规则:时间相同则离开事件优先bool operator<(const Event& other) const {if (fabs(time - other.time) < EPS) return type < other.type;return time < other.time;}
};int main() {ios_base::sync_with_stdio(false);cin.tie(nullptr);int testCaseCount;cin >> testCaseCount;while (testCaseCount--) {int width, height;cin >> width >> height;int meteorCount;cin >> meteorCount;vector<Event> events;for (int i = 0; i < meteorCount; ++i) {int startX, startY, velX, velY;cin >> startX >> startY >> velX >> velY;// 计算 X 方向的时间区间double xStartTime, xEndTime;if (velX > 0) {xStartTime = max(0.0, (-startX + EPS) / velX);xEndTime = (width - startX - EPS) / velX;} else if (velX < 0) {xStartTime = max(0.0, (width - startX + EPS) / velX);xEndTime = (-startX - EPS) / velX;} else { // velX == 0if (startX > 0 && startX < width) {xStartTime = 0.0;xEndTime = 1e20; // 表示无穷大} else {xStartTime = 1.0;xEndTime = 0.0; // 空区间}}// 计算 Y 方向的时间区间double yStartTime, yEndTime;if (velY > 0) {yStartTime = max(0.0, (-startY + EPS) / velY);yEndTime = (height - startY - EPS) / velY;} else if (velY < 0) {yStartTime = max(0.0, (height - startY + EPS) / velY);yEndTime = (-startY - EPS) / velY;} else { // velY == 0if (startY > 0 && startY < height) {yStartTime = 0.0;yEndTime = 1e20; // 表示无穷大} else {yStartTime = 1.0;yEndTime = 0.0; // 空区间}}// 取 X 和 Y 方向的交集double startTime = max(xStartTime, yStartTime);double endTime = min(xEndTime, yEndTime);// 如果区间有效,创建事件if (startTime < endTime - EPS) {events.emplace_back(startTime, 1);   // 进入事件events.emplace_back(endTime, -1);    // 离开事件}}// 按时间排序事件sort(events.begin(), events.end());int currentCount = 0;int maxCount = 0;// 扫描事件for (const auto& event : events) {currentCount += event.type;if (currentCount > maxCount) {maxCount = currentCount;}}cout << maxCount << "\n";}return 0;
}
http://www.dtcms.com/a/562834.html

相关文章:

  • wordpress仿站工具网站设计文字超链接
  • 网站建设制作的规划方案施工企业公司管理制度
  • 网站编辑转做新媒体运营营销手段和营销方式
  • 嵌入式板卡组成介绍
  • 骗别人做网站非法网站开发
  • 秦皇岛 免费建网站云主机搭建网站
  • 网站开发指什么马鞍山网站建设公
  • 全屏网站 图片优化网站开发程序说明
  • 浙江省城乡住房建设厅网站网站网页进口
  • 建立本地网站新建的网站必须要备案吗
  • 个人网站备案 备注泉州seo排名工具
  • 太仓市质监站网址零食网站建设描述书
  • 灰色网站建设优化响应式网站企业
  • 图像配准技术综述:从传统特征到深度学习
  • 微信小程序组件库企业网站优化案例
  • 做网站一个月工资企业网站与网络营销
  • 网站百度收录变少厦门企业制作网站方案
  • 江苏成章建设集团有限公司官方网站网络推广工作好吗
  • 做网站设计制作的公司网站设计建设维护
  • 做网站编辑器wordpress to cms
  • google中文搜索引擎入口福州网站设计知名乐云seo
  • 做响应式网站从美洲开始做皇帝免费阅读网站
  • 多态的介绍
  • 有没有做美食的小视频网站wordpress如何备份 网站
  • (125页PPT)盐化行业数字化转型规划详细方案(附下载方式)
  • 全站仪为什么要建站彬县网站
  • 学字体网站企业建网站品牌
  • OC母语的Developer对Swift常见问题的整理
  • 网站新闻置顶怎么做做企业品牌网站的公司
  • 网站建设开发团队介绍国外网站问题