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

UVa 191 Intersection

题目分析

给定一个线段(由起点和终点确定)和一个矩形(由左上角和右下角确定),需要判断线段与矩形是否有至少一个公共点。矩形由其边界线和内部区域组成。

题目中给出的坐标均为整数,但交点可以是任意实数点。矩形坐标的输入顺序为xleft ytop xright ybottom,但需要注意top leftbottom right仅表示名称,不保证xleft≤xrightxleft \leq xrightxleftxrightytop≥ybottomytop \geq ybottomytopybottom,因此需要自行处理坐标的大小关系。

解题思路

本题的核心是判断线段与矩形的相交关系。考虑以下几种相交情况:

  1. 线段与矩形的任意一条边相交。矩形的四条边可视为四个线段:上边、下边、左边、右边。
  2. 线段的一个端点在矩形内部。这种情况即使线段不与任何边相交,也与矩形有公共点。

因此解题分为两步:

  • 使用跨立实验判断线段是否与矩形的四条边相交。
  • 判断线段的两个端点是否至少有一个在矩形内部。

跨立实验判断线段相交

通过叉积判断方向:

设线段ABABABCDCDCD,计算:

d1=AB→×AC→d2=AB→×AD→d3=CD→×CA→d4=CD→×CB→ d_1 = \overrightarrow{AB} \times \overrightarrow{AC} \\ d_2 = \overrightarrow{AB} \times \overrightarrow{AD} \\ d_3 = \overrightarrow{CD} \times \overrightarrow{CA} \\ d_4 = \overrightarrow{CD} \times \overrightarrow{CB} \\d1=AB×ACd2=AB×ADd3=CD×CAd4=CD×CB

d1×d2<0d_1 \times d_2 < 0d1×d2<0d3×d4<0d_3 \times d_4 < 0d3×d4<0,则两线段严格相交。若有任一叉积为零,则需要判断对应端点是否落在另一线段上。

点在矩形内的判断

对于点(x,y)(x, y)(x,y),若:

min⁡(xleft,xright)≤x≤max⁡(xleft,xright) \min(xleft, xright) \leq x \leq \max(xleft, xright)min(xleft,xright)xmax(xleft,xright)

min⁡(ytop,ybottom)≤y≤max⁡(ytop,ybottom) \min(ytop, ybottom) \leq y \leq \max(ytop, ybottom)min(ytop,ybottom)ymax(ytop,ybottom)

则点在矩形内部(包含边界)。

算法步骤

  1. 读取测试用例个数nnn
  2. 对于每个测试用例,读取线段的起点、终点和矩形的两个角点坐标。
  3. 构造矩形的四条边线段。
  4. 分别判断线段与四条边是否相交,若任意一条相交则标记为相交。
  5. 判断线段的任一端点是否在矩形内部,若是则标记为相交。
  6. 根据标记输出TF

复杂度分析

每个测试用例进行常数次线段相交判断,时间复杂度O(1)O(1)O(1),空间复杂度O(1)O(1)O(1)

代码实现

// Intersection// UVa ID: 191// Verdict: Accepted// Submission Date: 2016-03-14// UVa Run Time: 0.000s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;// 定义点结构体structpoint{intx,y;};// 定义线段结构体structsegment{point start,end;};// 包围盒测试,判断点 p 是否在线段 ab 的包围盒内(包含边界)boolpointInBox(point p,point a,point b){return((p.x>=min(a.x,b.x))&&(p.x<=max(a.x,b.x))&&(p.y>=min(a.y,b.y))&&(p.y<=max(a.y,b.y)));}// 计算向量 AB 与 AC 的叉积// 返回值 > 0 表示 C 在 AB 的左侧,< 0 表示在右侧,= 0 表示共线doubledirection(point a,point b,point c){return(b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}// 判断两条线段是否相交(包含端点情况)boolsegmentsIntersect(segment a,segment b){doubled1,d2,d3,d4;// 计算叉积d1=direction(a.start,a.end,b.start);d2=direction(a.start,a.end,b.end);d3=direction(b.start,b.end,a.start);d4=direction(b.start,b.end,a.end);// 严格相交:两个端点分别位于另一线段两侧if((d1*d2<0)&&(d3*d4<0))returntrue;// 非严格相交:端点落在另一线段上if(d1==0&&pointInBox(b.start,a.start,a.end))returntrue;if(d2==0&&pointInBox(b.end,a.start,a.end))returntrue;if(d3==0&&pointInBox(a.start,b.start,b.end))returntrue;if(d4==0&&pointInBox(a.end,b.start,b.end))returntrue;returnfalse;}intmain(){intn,xstart,ystart,xend,yend,xleft,ytop,xright,ybottom;cin>>n;// 读取测试用例个数while(n>0){// 读取输入数据cin>>xstart>>ystart>>xend>>yend>>xleft>>ytop>>xright>>ybottom;segment line=(segment){(point){xstart,ystart},(point){xend,yend}};// 构造矩形的四个顶点point leftTop=(point){xleft,ytop};point rightTop=(point){xright,ytop};point leftBottom=(point){xleft,ybottom};point rightBottom=(point){xright,ybottom};boolintersected=false;// 判断线段是否与矩形的四条边相交if(segmentsIntersect(line,(segment){leftTop,rightTop}))// 上边intersected=true;if(segmentsIntersect(line,(segment){leftBottom,rightBottom}))// 下边intersected=true;if(segmentsIntersect(line,(segment){leftTop,leftBottom}))// 左边intersected=true;if(segmentsIntersect(line,(segment){rightTop,rightBottom}))// 右边intersected=true;// 判断线段端点是否在矩形内部if(min(xleft,xright)<=xstart&&xstart<=max(xleft,xright)&&min(ytop,ybottom)<=ystart&&ystart<=max(ytop,ybottom))intersected=true;if(min(xleft,xright)<=xend&&xend<=max(xleft,xright)&&min(ytop,ybottom)<=yend&&yend<=max(ytop,ybottom))intersected=true;// 输出结果cout<<(intersected?"T\n":"F\n");n--;}return0;}

注意事项

  • 矩形坐标输入顺序不保证xleft<xrightxleft < xrightxleft<xrightytop>ybottomytop > ybottomytop>ybottom,需使用min⁡\minminmax⁡\maxmax函数处理。
  • 线段与矩形相交包含线段完全在矩形内部的情况,此时线段不与任何边相交但端点在内,因此必须单独判断端点。
  • 线段完全在矩形外部但与某边延长线相交的情况,通过跨立实验可以正确排除。
http://www.jsqmd.com/news/788931/

相关文章:

  • 实战AI智能体技能库:设计、Telegram连接、多智能体协同与知识库部署
  • 不止看波形!用Vivado ILA抓取FPGA上电时序与异常复位(附触发设置技巧)
  • ChatGpt-Pro项目解析:从零构建企业级AI对话应用的技术实践
  • 别再死磕手册了!手把手教你用Vivado里的10G Ethernet MAC IP核(附仿真避坑指南)
  • OpenCore Legacy Patcher:让你的老旧Mac免费升级最新macOS的终极指南
  • 3分钟彻底搞定Figma汉化!设计师专属中文界面插件指南
  • AMD Ryzen终极调试指南:SMUDebugTool解锁处理器隐藏潜力
  • 2026济南名牌手表回收高价秘籍|靠谱门店盘点,变现更省心 - 奢侈品回收测评
  • 别再手动复制路径了!Win10下EVE-NG一键关联Wireshark的保姆级配置指南
  • GTX 1050 Ti + Win10 环境下的 PyTorch-GPU 一站式部署指南
  • AMD Ryzen处理器深度调优指南:使用SMUDebugTool解锁底层性能控制
  • UVa 192 Synchronous Design
  • BetterNCM Installer:3步搞定网易云音乐插件安装,告别手动操作烦恼
  • 百度网盘提取码智能获取工具:3秒破解资源密码的终极指南
  • 用Python和树莓派GPIO玩转DHT11:手把手教你读懂单总线通信时序图
  • AI+与+AI的关键之处
  • 别让自举电路‘举’不起来:深入IR2104数据手册,搞懂H桥高端驱动的门道
  • SAP PS模块实战:如何把固定资产折旧费精准归集到项目WBS上(ACSET配置详解)
  • Source Han Serif CN字体深度应用指南:从技术原理到专业排版实践
  • 微信小程序集成ChatGPT:自部署AI助手实战指南
  • QMC音频解码完全手册:三步解锁加密音乐文件
  • ChatGPT-System-Prompts项目解析:构建高效AI提示词的工程实践
  • 小红书数据采集实战指南:高效Python工具深度解析
  • WebLogic实战:从零搭建企业级应用服务器(安装、Domain配置与核心管理)
  • 视频加速控制器:掌控在线视频播放速度的终极解决方案
  • 如何3分钟永久禁用Windows Defender?开源工具Defender Control终极指南
  • 如何轻松解密微信聊天记录:开源工具的完整指南
  • 2025届必备的五大AI辅助写作平台推荐
  • AI原生超算架构解析:从异构计算到万卡集群的优化实践
  • UVa 193 Graph Coloring