UVa11726 Crime Scene

题目链接

         UVa11726 - Crime Scene

题意

        给定n(n≤100)个物体,每个物体都是一个圆或者k(k≤10)边形,用长度尽量小的绳子把它们包围起来。

分析

        孟加拉国Manzurur Rahman Khan (Sidky)大神出的难题,大神毕业于BUET(Bangladesh University of Engineering and Technology)。

        几何图形集合的凸包问题(凸包有两个最优性:长度最短;面积最小),本题的基本图形有圆,所以可以这么做:

        求出所有点和圆的切点,然后所有的点和原有的点一起做一次凸包,求出凸包的边长,如果连续的两个点都是同一个圆上的切点,计算长度的方式就要变成求弧长。

        这里不细说取巧的方法,而是详细探讨几何图形集合的凸包问题的一般求法,姑且叫滚边法吧:在所有图形中找到最低点,多个图形包含最低点时任取一个作为起点即可,初始时假想从起点水平往右的向量作为当前向量,找出逆时针最小旋转量使其刚好贴到下一个图形某点上,下一个图形如果是圆,则可以绕着切点逆时针转一定角度(注意:可能会转超过180度)再贴到其他图形的某一点上,依此不停滚边操作,直到回贴到起点。

        接下来说一些细节,先看这一份数据:

10
2
c 0 0 2
p 4 -1 2 1 2 1 -2 -1 -2
1
c 0 0 3
2
c 0 0 2
c 10 10 1
5
c 0 0 1
c 10 0 1
c 0 10 1
c 10 10 1
p 4 4 4 5 5 6 4 5 8
3
c 0 0 2
c 2 2 2
p 3 -1 2 1 4 3 -1
3
p 3 -2 5 2 5 4 8
c 5 -8 7
c -10 -1 9
4
p 2 -1 -8 -9 10
p 1 -5 -7
c -1 2 9
c 7 -7 1
3
p 2 9 2 -1 -5
p 4 9 -4 8 -4 -4 7 -3 -7
c 2 3 7
5
p 2 5 2 -1 -9
c 9 -7 8
p 2 -9 9 -2 9
c -4 1 8
p 3 -10 -9 4 3 -7 -9
6
p 1 1 -10
p 1 2 5
p 1 -5 2
c 3 -1 1
p 7 8 -4 -8 9 -1 10 -4 -5 -6 9 -9 -6 -9 -1
c -3 -6 4

        其正确输出应该是:

Case #1: 13.148009
Case #2: 18.849556
Case #3: 37.779789
Case #4: 46.283185
Case #5: 18.749469
Case #6: 87.092793
Case #7: 63.571176
Case #8: 51.636719
Case #9: 84.282670
Case #10: 59.374851

        以上结果可以利用可视化脚本画图再手算检验。

        后面几条数据容易出错,调试发现坑在double精度及反三角函数acos这里,acos函数传参必须严格在[-1,1]区间,否则会得到nan,因此可以这样处理:

double safe_acos(double v) {return acos(min(max(v, -1.), 1.));
}

        但更推荐另外一种方式:计算余弦值的过程中用long double保精度因此能严格在[-1,1]区间,这样就可以直接调用acos了(可以将下面AC代码里面的long double全部换成double再提交验证,会WA)。

AC代码

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;#define eps 1e-10
struct Point {double x, y;Point(double x = 0., double y = 0.): x(x), y(y) {}
};
typedef Point Vector;Vector operator- (const Vector& A, const Vector& B) {return Vector(A.x - B.x, A.y - B.y);
}int dcmp(double x) {return abs(x) < eps ? 0 : (x < 0. ? -1 : 1);
}bool operator== (const Point& a, const Point& b) {return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}double Cross(const Vector& A, const Vector& B) {return A.x * B.y - A.y * B.x;
}double Dot(const Vector& A, const Vector& B) {return A.x * B.x + A.y * B.y;
}double Lsq(const Vector& A) {return A.x*A.x + A.y*A.y;
}#define N 102
Point c[N], p[11*N]; double r[N], pi2 = M_PI + M_PI; int n; bool esc0[N], esc[11*N];double solve() {cin >> n;int a = 0, b = 0;while (n--) {char ch; cin >> ch;if (ch == 'p') {int k; cin >> k;while (k--) cin >> p[b].x >> p[b].y, esc[b++] = false;} else cin >> c[a].x >> c[a].y >> r[a], esc0[a++] = false;}for (int i=0; i<a; ++i) if (!esc0[i]) for (int j=i+1; j<a; ++j) {if (dcmp(r[i]-r[j]) <= 0 && dcmp(sqrt(Lsq(c[i]-c[j])) - r[j]+r[i]) <= 0) {esc0[i] = true; break;}if (dcmp(r[i]-r[j]) > 0 && dcmp(sqrt(Lsq(c[i]-c[j])) - r[i]+r[j]) <= 0) esc0[j] = true;}for (int i=0; i<b; ++i) if (!esc[i]) {for (int j=i+1; j<b; ++j) if (p[i] == p[j]) {esc[i] = true; break;}if (esc[i]) continue;for (int j=0; j<a; ++j) if (dcmp(sqrt(Lsq(p[i]-c[j])) - r[j]) <= 0) {esc[i] = true; break;}}for (int j=a, i=a=0; i<j; ++i) if (!esc0[i]) c[a] = c[i], r[a++] = r[i];for (int j=b, i=b=0; i<j; ++i) if (!esc[i]) p[b++] = p[i];if (a == 1 && b == 0) return pi2 * r[0];if (a == 0 && b < 2) return 0.;int s = 0; bool f = a>0;for (int i=0; i<a; ++i) if (c[i].y-r[i] < c[s].y-r[s]) s = i;for (int i=0; i<b; ++i) {if (f) {if (p[i].y < c[s].y-r[s]) s = i, f = false;} else if (p[i].y < p[s].y) s = i;}double t = 0., g = 0.; int x = s; bool u = f; Vector v(1.);while (true) {int y = -1; bool q; long double h;if (u) {for (int i=0; i<a; ++i) if (i != x) {Vector z = c[i] - c[x]; long double l = sqrt(Lsq(z)), sin = (r[i]-r[x])/l, cos = sqrt(1.-sin*sin);Vector w(z.x*cos + z.y*sin, z.y*cos - z.x*sin);cos = dcmp(Cross(v, w)) < 0 ? -2. - Dot(v, w) / l : Dot(v, w) / l;if (y < 0 || dcmp(cos-h) > 0) y = i, h = cos, q = true;}for (int i=0; i<b; ++i) {Vector z = p[i] - c[x]; long double l = sqrt(Lsq(z)), sin = r[x]/l, cos = sqrt(1.-sin*sin);Vector w(z.x*cos - z.y*sin, z.y*cos + z.x*sin);cos = dcmp(Cross(v, w)) < 0 ? -2. - Dot(v, w) / l : Dot(v, w) / l;if (y < 0 || dcmp(cos-h) > 0) y = i, h = cos, q = false;}h = h < -1. ? pi2-acos(-2.-h) : acos(h);if (f && x==s && dcmp(g + h - pi2) >= 0) return t + (pi2-g)*r[s];t += h*r[x] + (q ? sqrt(Lsq(c[y] - c[x]) - (r[y]-r[x])*(r[y]-r[x])) : sqrt(Lsq(p[y] - c[x]) - r[x]*r[x]));if (!f && !q && y==s) return t;g += h; x = y; u = q; v.x = cos(g); v.y = sin(g);} else {for (int i=0; i<a; ++i) {Vector z = c[i] - p[x]; long double l = sqrt(Lsq(z)), sin = r[i]/l, cos = sqrt(1.-sin*sin);Vector w(z.x*cos + z.y*sin, z.y*cos - z.x*sin);if (dcmp(Cross(v, w)) < 0) continue;cos = Dot(v, w) / l;if (y < 0 || dcmp(cos-h) > 0) y = i, h = cos, q = true;}for (int i=0; i<b; ++i) if (i != x) {Vector w = p[i] - p[x];if (dcmp(Cross(v, w)) < 0) continue;long double cos = Dot(v, w) / sqrt(Lsq(w));if (y < 0 || dcmp(cos-h) > 0) y = i, h = cos, q = false;}h = acos(h);t += q ? sqrt(Lsq(c[y] - p[x]) - r[y]*r[y]) : sqrt(Lsq(p[y] - p[x]));if (!f && !q && y==s) return t;g += h; x = y; u = q; v.x = cos(g); v.y = sin(g);}}return t;
}int main() {ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);cout << fixed << setprecision(6);int t; cin >> t;for (int kase=1; kase<=t; ++kase) cout << "Case #" << kase << ": " << solve() << endl;return 0;
}

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

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

相关文章

MySQL 核心模块揭秘 | 07 期 | 二阶段提交 (1) prepare 阶段

二阶段提交的 prepare 阶段&#xff0c;binlog 和 InnoDB 各自会有哪些动作&#xff1f; 本文基于 MySQL 8.0.32 源码&#xff0c;存储引擎为 InnoDB。 1. 二阶段提交 二阶段提交&#xff0c;顾名思义&#xff0c;包含两个阶段&#xff0c;它们是&#xff1a; prepare 阶段。…

springboot-基础-eclipse配置+helloword示例

备份笔记。所有代码都是2019年测试通过的&#xff0c;如有问题请自行搜索解决&#xff01; 下一篇&#xff1a;springboot-基础-添加model和controller的简单例子常用注解含义 目录 配置helloword示例新建项目创建文件 配置 spring boot官方有定制版eclipse&#xff0c;也就是…

BUUCTF AWD-Test1

打开靶场是这个有些简陋的界面。 随便点点&#xff0c;找到这个东西。 看到ThinkPHP&#xff0c;思路瞬间清晰&#xff0c;老熟人了。这个就是ThinkPHP漏洞。根据版本我们去找一下poc。 /index.php/?sIndex/\think\View/display&content%22%3C?%3E%3C?php%20phpinfo();…

SHELL 脚本: 导出NEO4j DUMP并上传SFTP

前提 开通sftp账号 安装expect 示例 NEO4J_HOME/path/to/neo4j # neo4j 安装目录 DUMP_PATH/data/dump # DUMP本地保存目录 DUMP_FILEneo4j_$(date %F).dump #导出文件名称 UPLOAD_DIR/path/to/stfp/dump/ #上传目录 $NEO4J_HOME/bin/neo4j-admin dump --databaseneo4j --t…

Vue-5

Vue 3 的优势 更容易维护&#xff08;组合式API&#xff09;更快的速度更小的体积更优的数据响应 创建 Vue 3 项目 前提环境条件&#xff1a;已安装 16.0 或更高版本的 Node.js node -v创建一个 Vue 应用&#xff08;下面的指令将会安装并执行 create-vue &#xff09; np…

服务端向客户端推送数据的实现方案

在日常的开发中&#xff0c;我们经常能碰见服务端需要主动推送给客户端数据的业务场景&#xff0c;比如数据大屏的实时数据&#xff0c;比如消息中心的未读消息&#xff0c;比如聊天功能等等。 本文主要介绍SSE的使用场景和如何使用SSE。 服务端向客户端推送数据的实现方案有哪…

MySQL 自增列解析(Auto_increment)

MySQL数据库为列提供了一种自增属性&#xff0c;当列被定义为自增时。Insert语句对该列即使不提供值&#xff0c;MySQL也会自动为该列生成递增的唯一标识&#xff0c;因此这个特性广泛用于主键的自动生成。 一、自增列的用法 自增列具有自动生成序列值&#xff0c;整型&#…

职责链模式(Chain of Responsibility Pattern)

定义 职责链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许对象接收请求并将其沿着处理者链传递&#xff0c;直到有一个处理者处理它为止。职责链模式通过将请求的处理逻辑分布 在职责链模式中&#xff0c;通常包含以下几…

MYSQL04高级_逻辑架构剖析、查询缓存、解析器、优化器、执行器、存储引擎

文章目录 ①. 逻辑架构剖析②. 服务层 - 查询缓存③. 服务层 - 解析器④. 服务层 - 优化器⑤. 服务层 - 执行器⑥. MySQL8执行原理 ①. 逻辑架构剖析 ①. 服务器处理客户端请求 ②. 连接层 系统(客户端)访问MySQL服务器前,做的第一件事就是建立TCP连接经过三次握手建立连接成…

Linux使用C语言实现通过互斥锁限制对共享资源的访问

互斥锁限制共享资源的访问 主线程中有两个线程&#xff0c;分别输出信息。 #include <stdio.h> #include <pthread.h> #include <unistd.h>int g_data0;void* fun1(void *arg) {printf("t1&#xff1a;%ld thread is create\n", (unsigned long)…

大宋咨询数据研究在汽车新品上市中的核心作用

随着汽车行业的快速变革&#xff0c;数据研究已经成为新品上市流程中的不可或缺的一环。从市场定位、产品规划到营销策略&#xff0c;数据研究不仅为汽车企业提供了独特的洞察&#xff0c;还为其提供了决策依据&#xff0c;确保新品在竞争激烈的市场中取得优势。在这一领域&…

Kubernetes IoTDB系列 | IoTDB搭建 | v1.3.0

目录 一、IoTDB 介绍二、k8s 部署 IoTDB一、IoTDB 介绍 IoTDB 是一种面向物联网(IoT)场景的开源时序数据库。它专门设计用于高效地存储和查询大规模物联网设备产生的时序数据。IoTDB 提供了高吞吐量、低延迟、灵活的数据模型以及多种数据查询和存储引擎等特性,使其成为处理…

稀疏图带负边的全源最短路Johnson算法

BellmanFord算法 Johnson算法解决的问题 带负权的稀疏图的全源最短路 算法流程 重新设置的每条边的权重都大于或等于0&#xff0c;跑完Djikstra后得到的全源最短路&#xff0c;记得要还原&#xff0c;即&#xff1a;f(u,v) d(u,v) - h[u] h[v] 例题

45、WEB攻防——通用漏洞PHP反序列化POP链构造魔术方法原生类

文章目录 序列化&#xff1a;将java、php等代码中的对象转化为数组或字符串等格式。代表函数serialize()&#xff0c;将一个对象转换成一个字符&#xff1b;反序列化&#xff1a;将数组或字符串等格式还成对象。代表函数unserialize()&#xff0c;将字符串还原成一个对象。 P…

MWC 2024丨Smart Health搭载高通Aware平台—美格发布智能健康看护解决方案,开启健康管理新体验

2月29日&#xff0c;在MWC 2024世界移动通信大会上&#xff0c;全球领先的无线通信模组及解决方案提供商——美格智能正式发布了新一代Cat.1模组SLM336Q&#xff0c;是中低速物联网应用场景的高性价比之选。本次还发布了首款搭载高通Aware™平台的智能看护解决方案MC303&#x…

[万字长文] 从 Vue 3 的项目模板学习 tsconfig 配置

文章目录 一、tsconfig.json 的作用二、基本介绍三、Vue 3 的 tsconfig.json 的结构分析1. 总配置 tsconfig.json2. Web 侧 tsconfig.app.jsona. 继承基础配置b. 包含和排除的文件c. 编译器选项 3. 测试 tsconfig.vitest.jsona. 继承的基础配置b. 包含和排除的文件c. 编译器选项…

OD(13)之Mermaid饼图和象限图

OD(13)之Mermaid饼图和象限图使用详解 Author: Once Day Date: 2024年2月29日 漫漫长路才刚刚开始… 全系列文章可参考专栏: Mermaid使用指南_Once_day的博客-CSDN博客 参考文章: 关于 Mermaid | Mermaid 中文网 (nodejs.cn)Mermaid | Diagramming and charting tool‍‌⁡…

FPGA-学会使用vivado中的存储器资源RAM(IP核)

问题 信号源(例如ADC)以1us一个的速率产生12位的数据现要求获得连续1ms内的数据,通过串口以115200的波特率发到电脑。 分析 数据量是1000个 数据速率不匹配 数据内容未知 数据总数据量有限 数据的使用速度低于数据的产生速度 数据生产和消耗的位宽 数据量相对较…

ywtool check命令及ywtool clean命令

一.ywtool check命令 1.1 ywtool check -I 1.2 ywtool check all 1.3 ywtool check io 1.4 ywtool check elk 1.5 ywtool check php 1.6 ywtool check mysql 1.7 ywtool check nginx 1.8 ywtool check system 1.9 ywtool check docker_nbip [容器名称] 1.10 ywtool check 1.10…

综合练习(一)

目录 列出薪金高于部门 30 的所有员工薪金的员工姓名和薪金、部门名称、部门人数 列出与 ALLEN从事相同工作的所有员工及他们的部门名称、部门人数、领导姓名 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 列出薪金高于部门 30 的所…