UVa 132 Bumpy Objects

问题描述

题目定义了一类“凹凸不平的物体”(Bumpy Objects\texttt{Bumpy Objects}Bumpy Objects)。每个物体由一个多边形表示,已知其质心坐标和按逆时针顺序排列的顶点坐标。

一个物体能够稳定旋转站立的条件是:存在两个顶点,可以用一条不与物体相交的直线将它们连接起来,并且当这条直线水平时,质心位于该直线上方,且严格位于两个端点的投影之间。满足上述条件的这条直线称为物体的基线(base line\texttt{base line}base line。一个物体通常有多个稳定位置(对应多条基线)。每条基线由其接触到的编号最大的顶点来标识(顶点编号从111开始,按逆时针顺序递增)。

题目要求:对于给定的物体,找到所有稳定位置中,基线标识号最小的那个位置,并输出其基线标识号。

输入包含多个数据集,每个数据集包含:

  1. 一个长度小于202020的字符串,表示物体名称。
  2. 两个整数,表示质心的坐标。
  3. 多对整数,表示多边形顶点的坐标,以0 0结束。
    所有数据集以单个#结束。

输出对于每个物体,输出其名称和满足条件的最小基线标识号。

题目分析与建模

关键条件解读

  1. 基线定义:基线是连接两个顶点的线段,且线段本身不与多边形相交(即,是多边形的一条“支撑弦”)。
  2. 稳定条件
    • 当这条线段被放置为水平时,质心必须在它的正上方。
    • 质心在水平方向上的投影,必须严格位于线段两个端点的投影之间(即,不能与端点重合)。
  3. 基线标识:由线段接触到的编号最大的顶点决定。因此,我们需要记录每个顶点的原始输入编号。

核心难点与突破口

  1. 几何搜索范围:一个凹多边形的潜在基线数量可能很多(任意两个顶点都可能)。但是,根据物理直觉和几何性质,只有凸包(Convex Hull\texttt{Convex Hull}Convex Hull)上的边或弦,才有可能成为有效的基线。为什么?
    • 如果一条边在凸包内部,那么它必然与多边形自身相交(因为它穿过了多边形的“内部”),这违反了基线“不与物体相交”的条件。
    • 因此,所有有效的基线,其两个端点必然是多边形凸包的顶点。更进一步,基线本身必须是凸包的一条边,或者是凸包的一条弦(连接两个非相邻凸包顶点的线段)
  2. 稳定条件判定:对于一个候选的基线(A,B)(A, B)(A,B),设其被旋转至水平。要判断质心CCC是否在其上方且投影严格在A,BA, BA,B之间,可以等价于判断以下两个条件(在原始坐标系下):
    • 上方性:质心CCC位于有向直线ABABAB左侧(假设顶点是逆时针排列,那么多边形内部在每条边的左侧)。用叉积判断:(B−A)×(C−A)>0(B-A) \times (C-A) > 0(BA)×(CA)>0
    • 投影在内部:这等价于角∠ACB\angle ACBACB∠BCA\angle BCABCA都是锐角。如果质心投影在线段端点之外,那么其中一个角将是钝角或直角(当投影与端点重合时)。因此,我们可以通过余弦定理a2+b2>c2a^2 + b^2 > c^2a2+b2>c2来判断一个角是否为锐角。

算法思路

  1. 输入与存储:读入物体名称和质心坐标。读入所有顶点,并记录其原始输入序号(从 1 开始)
  2. 求凸包:使用Andrew\texttt{Andrew}Andrew算法(或称单调链算法)求出所有顶点的凸包。该算法能O(nlog⁡n)O(n \log n)O(nlogn)时间内得到按逆时针顺序排列的凸包顶点序列。
  3. 枚举候选基线:遍历凸包上的所有(相邻顶点对)。根据分析,只需检查凸包的边。
    • 对于凸包的边(Vi,Vi+1)(V_i, V_{i+1})(Vi,Vi+1),检查它是否可能是一条有效基线:
      • 条件111:质心CCC是否位于该边的左侧cw(V_i, V_{i+1}, C)true)。注意,代码中的cw函数(clockwise\texttt{clockwise}clockwise)判断点是否在向量右侧,由于顶点是逆时针的,多边形内部在左侧,所以这里判断质心在右侧,即从多边形的“外部”看,质心在边的上方。这与分析中的“左侧”是等价的,只是坐标系和判断函数实现的差异。
      • 条件222&333:角∠(C,Vi,Vi+1)\angle (C, V_i, V_{i+1})(C,Vi,Vi+1)和角∠(C,Vi+1,Vi)\angle (C, V_{i+1}, V_i)(C,Vi+1,Vi)是否都是锐角(isAcuteAngle函数)。
  4. 计算基线标识并更新:如果当前凸包的边满足以上三个条件,那么它就是一个稳定位置对应的基线。这条基线接触到的顶点是ViV_iViVi+1V_{i+1}Vi+1。根据题目定义,该基线的标识号为这两个顶点原始编号的较大值。我们需要在所有满足条件的基线中,找到这个标识号的最小值
  5. 输出结果:输出物体名称和找到的最小基线标识号。

复杂度分析

  • 时间复杂度
    • 凸包计算:O(nlog⁡n)O(n \log n)O(nlogn),其中nnn为顶点数。
    • 凸包边枚举与条件判断:O(n)O(n)O(n)
    • 总体复杂度为O(nlog⁡n)O(n \log n)O(nlogn),对于n≤100n \leq 100n100的数据范围非常高效。
  • 空间复杂度O(n)O(n)O(n),用于存储顶点和凸包。

代码实现

// Bumpy Objects// UVa ID: 132// Verdict: Accepted// Submission Date: 2015-12-11// UVa Run Time: 0.000s//// 版权所有(C)2015,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;#defineMAX_VERTICES105#defineEPSILON1E-10structpoint{intx;inty;intindex;// 顶点的原始编号};structpolygon{intnumber;// 顶点数point vertex[MAX_VERTICES];// 顶点数组};// 计算叉积 (c - a) x (b - a)intcrossProduct(point a,point b,point c){return(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);}// 判断点 c 是否在向量 ab 的顺时针方向(右侧)boolcw(point a,point b,point c){returncrossProduct(a,b,c)>EPSILON;}// 判断点 c 是否在向量 ab 的逆时针方向(左侧)boolccw(point a,point b,point c){returncrossProduct(a,b,c)<-EPSILON;}// 判断三点是否共线boolcollinear(point a,point b,point c){returnfabs(crossProduct(a,b,c))<=EPSILON;}// 判断点 c 在向量 ab 的左侧或共线boolccwOrCollinear(point a,point b,point c){returnccw(a,b,c)||collinear(a,b,c);}// 排序比较函数:先按 y 坐标升序,y 相同则按 x 坐标升序boollowerLeft(point a,point b){return(a.y==b.y)?(a.x<b.x):(a.y<b.y);}// Andrew 凸包算法(单调链)voidandrewConvexHull(point vertex[],intnumber,polygon&hull){// 1. 按 lowerLeft 规则排序sort(vertex,vertex+number,lowerLeft);point upper[MAX_VERTICES],lower[MAX_VERTICES];inttop;// 2. 构造上凸包upper[0]=vertex[0];upper[1]=vertex[1];top=2;for(inti=2;i<number;i++){upper[top]=vertex[i];// 当新点导致上凸包出现“右转”或“直行”时,删除栈顶的点while(top>=2&&ccwOrCollinear(upper[top-2],upper[top-1],upper[top])){upper[top-1]=upper[top];top--;}top++;}// 将上凸包的点存入结果 hullhull.number=0;for(inti=0;i<top;i++)hull.vertex[hull.number++]=upper[i];// 3. 构造下凸包lower[0]=vertex[number-1];lower[1]=vertex[number-2];top=2;for(inti=number-3;i>=0;i--){lower[top]=vertex[i];// 同理,删除导致“右转”或“直行”的点while(top>=2&&ccwOrCollinear(lower[top-2],lower[top-1],lower[top])){lower[top-1]=lower[top];top--;}top++;}// 将下凸包的点(去掉首尾,避免重复)加入结果 hullfor(inti=1;i<top-1;i++)hull.vertex[hull.number++]=lower[i];}// 计算两点距离的平方(避免开方)doubledistances(point a,point b){returnpow(a.x-b.x,2)+pow(a.y-b.y,2);}// 根据余弦定理判断角 abc 是否为锐角。// 对于角 ABC,边为 a = |B-C|, b = |A-C|, c = |A-B|。// 余弦定理:cos(B) = (a^2 + c^2 - b^2) / (2ac)。// 角 B 为锐角当且仅当 cos(B) > 0,即 a^2 + c^2 - b^2 > 0。boolisAcuteAngle(point a,point b,point c){doubleA=distances(b,c),B=distances(a,c),C=distances(a,b);return(A+C-B)>0;}// 在凸包中寻找最小基线编号intlowestNumber(polygon pg,point center,intnumber){intminNumber=number;// 初始化为顶点总数(一个上界)for(inti=0;i<pg.number;i++){point p1=pg.vertex[i];point p2=pg.vertex[(i+1)%pg.number];// 检查三个条件:// 1. 质心在凸包边的“上方”(cw 判断)// 2. 角 <center, p1, p2> 是锐角// 3. 角 <center, p2, p1> 是锐角if(cw(p1,p2,center)&&isAcuteAngle(p1,p2,center)&&isAcuteAngle(p2,p1,center)){// 基线标识号为两个端点原始编号的较大值intlineNumber=max(p1.index,p2.index);minNumber=min(minNumber,lineNumber);}}returnminNumber;}intmain(){point tile[MAX_VERTICES],centerOfMass;polygon container;string name;// 循环读取每个物体,直到遇到 "#"while(cin>>name,name!="#"){cout<<name;// 先输出名称cin>>centerOfMass.x>>centerOfMass.y;intx,y,number=0;// 读取顶点,直到遇到 0 0while(cin>>x>>y,x||y){// 存储顶点,并记录其原始序号(从1开始)tile[number]=(point){x,y,number+1};number++;}// 计算顶点的凸包andrewConvexHull(tile,number,container);// 在凸包上寻找最小基线标识号并输出cout<<" "<<lowestNumber(container,centerOfMass,number)<<endl;}return0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1138874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序二维码生成终极指南:从零到精通的完整教程

微信小程序二维码生成终极指南&#xff1a;从零到精通的完整教程 【免费下载链接】weapp-qrcode 微信小程序快速生成二维码&#xff0c;支持回调函数返回二维码临时文件 项目地址: https://gitcode.com/gh_mirrors/weap/weapp-qrcode weapp-qrcode 是一款专为微信小程序…

OCLP-Mod完整使用指南:让老款Mac焕发新生

OCLP-Mod完整使用指南&#xff1a;让老款Mac焕发新生 【免费下载链接】OCLP-Mod A mod version for OCLP,with more interesting features. 项目地址: https://gitcode.com/gh_mirrors/oc/OCLP-Mod 还在为你的经典Mac设备被苹果官方抛弃而烦恼吗&#xff1f;OCLP-Mod作为…

PDF字体嵌入完整指南:3步彻底解决跨设备显示异常

PDF字体嵌入完整指南&#xff1a;3步彻底解决跨设备显示异常 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱&#xff0c;可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档&#xff0c;探查文档结构&#xff0c;提取图片、转成图片等等 项目地址: https://gitcode…

OCLP-Mod终极指南:让老旧Mac完美运行最新macOS系统

OCLP-Mod终极指南&#xff1a;让老旧Mac完美运行最新macOS系统 【免费下载链接】OCLP-Mod A mod version for OCLP,with more interesting features. 项目地址: https://gitcode.com/gh_mirrors/oc/OCLP-Mod 还在为你的Mac设备被苹果官方抛弃而苦恼吗&#xff1f;OCLP-M…

Qwen3-VL工业自动化:视觉引导机器人教程

Qwen3-VL工业自动化&#xff1a;视觉引导机器人教程 1. 引言&#xff1a;为何选择Qwen3-VL进行工业自动化&#xff1f; 在智能制造与工业4.0的浪潮中&#xff0c;视觉引导机器人&#xff08;Vision-Guided Robotics, VGR&#xff09; 正成为产线自动化的核心技术。传统方案依…

终极游戏自动化助手:彻底解放你的游戏时间

终极游戏自动化助手&#xff1a;彻底解放你的游戏时间 【免费下载链接】AhabAssistantLimbusCompany AALC&#xff0c;大概能正常使用的PC端Limbus Company小助手 项目地址: https://gitcode.com/gh_mirrors/ah/AhabAssistantLimbusCompany 还在为每天重复的游戏任务感到…

终极指南:如何快速搭建免费自托管轻量级监控工具

终极指南&#xff1a;如何快速搭建免费自托管轻量级监控工具 【免费下载链接】nezha :trollface: Self-hosted, lightweight server and website monitoring and O&M tool 项目地址: https://gitcode.com/GitHub_Trending/ne/nezha 想要全面掌握服务器运行状态却担心…

像素字体设计深度解析:Fusion Pixel Font技术架构与高级应用

像素字体设计深度解析&#xff1a;Fusion Pixel Font技术架构与高级应用 【免费下载链接】fusion-pixel-font 开源像素字体。支持 8、10 和 12 像素。 项目地址: https://gitcode.com/gh_mirrors/fu/fusion-pixel-font Fusion Pixel Font作为一款开源像素风格字体项目&a…

FinBERT实战指南:金融文本智能分析的完整解决方案

FinBERT实战指南&#xff1a;金融文本智能分析的完整解决方案 【免费下载链接】FinBERT A Pretrained BERT Model for Financial Communications. https://arxiv.org/abs/2006.08097 项目地址: https://gitcode.com/gh_mirrors/finbe/FinBERT 在当今信息爆炸的金融世界中…

Zotero PDF翻译插件:学术研究的智能翻译助手

Zotero PDF翻译插件&#xff1a;学术研究的智能翻译助手 【免费下载链接】zotero-pdf2zh PDF2zh for Zotero | Zotero PDF中文翻译插件 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-pdf2zh 还在为阅读英文文献而烦恼吗&#xff1f;Zotero PDF翻译插件为你提供了…

多校实行:大学教师,岗位降级!

2025年底&#xff0c;多所高校启动年度考核工作&#xff0c;规定考核不过的教职工将被降级、分流甚至解聘。华中科技大学发布的《关于做好2024年教职工年度考核工作的通知》中提到&#xff0c;考核结果为不合格档次的&#xff0c;次年薪级工资不得晋升&#xff1b;相应核减绩效…

Qwen3-VL-WEBUI快速上手:4步完成WEBUI环境部署教程

Qwen3-VL-WEBUI快速上手&#xff1a;4步完成WEBUI环境部署教程 1. 引言 随着多模态大模型的快速发展&#xff0c;视觉-语言理解能力已成为AI应用的核心竞争力之一。阿里云推出的 Qwen3-VL 系列模型&#xff0c;作为迄今为止Qwen系列中最强大的视觉-语言模型&#xff0c;不仅在…

AtlasOS系统优化实战:从配置到监控的完整指南

AtlasOS系统优化实战&#xff1a;从配置到监控的完整指南 【免费下载链接】Atlas &#x1f680; An open and lightweight modification to Windows, designed to optimize performance, privacy and security. 项目地址: https://gitcode.com/GitHub_Trending/atlas1/Atlas …

Google Map Downloader 完整使用指南

Google Map Downloader 完整使用指南 【免费下载链接】google-map-downloader Small tools to download Google maps satellite image for a given extent & zoom level to a TIFF file with geographical coordinates and speeding it up with multiple threads and proce…

FinBERT实战指南:金融文本分析的AI革命

FinBERT实战指南&#xff1a;金融文本分析的AI革命 【免费下载链接】FinBERT A Pretrained BERT Model for Financial Communications. https://arxiv.org/abs/2006.08097 项目地址: https://gitcode.com/gh_mirrors/finbe/FinBERT 作为一名金融分析师&#xff0c;你是否…

3步搞定Unity游戏微信小游戏移植:新手避坑全攻略

3步搞定Unity游戏微信小游戏移植&#xff1a;新手避坑全攻略 【免费下载链接】minigame-unity-webgl-transform 微信小游戏Unity引擎适配器文档。 项目地址: https://gitcode.com/GitHub_Trending/mi/minigame-unity-webgl-transform 想要把辛苦开发的Unity游戏快速搬到…

终极窗口管理神器:alt-tab-macos完全配置指南

终极窗口管理神器&#xff1a;alt-tab-macos完全配置指南 【免费下载链接】alt-tab-macos Windows alt-tab on macOS 项目地址: https://gitcode.com/gh_mirrors/al/alt-tab-macos alt-tab-macos是一款专为macOS用户设计的革命性窗口管理工具&#xff0c;将Windows系统…

终极无损音乐下载神器:网易云高品质音频一键获取完整指南

终极无损音乐下载神器&#xff1a;网易云高品质音频一键获取完整指南 【免费下载链接】Netease_url 网易云无损解析 项目地址: https://gitcode.com/gh_mirrors/ne/Netease_url 还在为找不到高品质音乐资源而烦恼吗&#xff1f;想要轻松获取专业级别的无损音乐文件来打造…

快速理解Keil C51在Win10中的安装要点

如何在 Windows 10 上稳稳装好 Keil C51&#xff1f;一篇讲透所有坑点与实战技巧 你是不是也遇到过这种情况&#xff1a;兴致勃勃准备开始学单片机&#xff0c;下载了 Keil C51 安装包&#xff0c;双击运行后刚点“下一步”就弹错&#xff1b;或者安装完了打开 uVision&#x…

TikTok API完整教程:从零开始掌握数据获取技巧

TikTok API完整教程&#xff1a;从零开始掌握数据获取技巧 【免费下载链接】tiktok-api Unofficial API wrapper for TikTok 项目地址: https://gitcode.com/gh_mirrors/tik/tiktok-api TikTok API是一款强大的非官方数据获取工具&#xff0c;为开发者和数据分析师提供了…