UVa1308/LA2572 Viva Confetti

题目链接

         本题是2002年ICPC亚洲区域赛金沢(日本)赛区的H题

题意

        我已经把n个圆盘依次放到了桌面上。现按照放置顺序依次给出各个圆盘的圆心位置和半径,问最后有多少圆盘可见?如下图所示。

分析

       《训练指南》的题解:

        题目说“保证在对输入数据进行微小扰动后答案不变”,意味着圆盘的可见部分不会太小。不难发现,每个可见部分都是由一些“小圆弧”围成的,因此可以先求出所有小圆弧,然后判断每段小圆弧是否可见(在程序实现中,可以用圆弧中点代替整条圆弧进行判断)。小圆弧可见,意味着它所在的圆是可见的。接下来,对于所有可见的小圆弧,看看这段圆弧中点的正下方都有哪些圆盘,则其中最顶部的圆盘也是可见的(想一想,为什么)。
        如何求出所有小圆弧?所有圆两两求交点,则每个圆上任两个相邻交点之间的圆弧就是所求。需要注意的是,如果一个圆不和其他所有圆相交,则整个圆是一条所求圆弧。

        这个思路真的很巧,特此写一篇笔记加强印象,还有一些细节参见AC代码。

        这里给一份测试数据,以及我用python写的画图可视化分析数据的脚本,能方便看出每个圆被其上面有相交的那些圆的覆盖情况:

AC代码

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;#define N 102
double a[N][N<<1], x[N], y[N], r[N], z = M_PI + M_PI; bool vis[N], esc[N]; int c[N], n;double check(double x) {return x > M_PI ? x-z : (x < -M_PI ? x+z : x);
}void judge(int i, double a) {double px = x[i] + r[i]*cos(a), py = y[i] + r[i]*sin(a);for (int j=i+1; j<n; ++j) if (sqrt((px-x[j])*(px-x[j])+(py-y[j])*(py-y[j])) < r[j]) return;vis[i] = 1;for (int j=i-1; j>=0; --j) if (sqrt((px-x[j])*(px-x[j])+(py-y[j])*(py-y[j])) < r[j]) {vis[j] = 1; return;}
}void solve() {for (int i=0; i<n; ++i) cin >> x[i] >> y[i] >> r[i], c[i] = vis[i] = esc[i] = 0;for (int i=0; i<n; ++i) for (int j=i+1; j<n; ++j) {double dx = x[i]-x[j], dy = y[i]-y[j], d = sqrt(dx*dx + dy*dy);if (d <= max(r[i], r[j])-min(r[i], r[j])) {if (r[i] <= r[j]) esc[i] = 1;continue;}if (d < r[i]+r[j]) {double x = atan2(dy, dx), b = acos((d*d+r[j]*r[j]-r[i]*r[i])/d/r[j]/2),y = M_PI - acos((d*d+r[i]*r[i]-r[j]*r[j])/d/r[i]/2);a[j][c[j]++] = check(x+b); a[j][c[j]++] = check(x-b);a[i][c[i]++] = check(x+y); a[i][c[i]++] = check(x-y);}}for (int i=0; i<n; ++i) {if (esc[i]) continue;if (c[i]) {sort(a[i], a[i]+c[i]);judge(i, (a[i][c[i]-1] + a[i][0]) / 2 + M_PI);for (int j=c[i]-1; j>0; --j) judge(i, (a[i][j-1] + a[i][j]) / 2);} else vis[i] = 1;}int ans = 0;for (int i=0; i<n; ++i) if (vis[i]) ++ans;cout << ans << endl;
}int main() {while (cin >> n && n) solve();return 0;
}

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

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

相关文章

Kafka配置Kerberos安全认证及与Java程序集成

Background 本文主要介绍在 Kafka 中如何配置 Kerberos 认证&#xff0c;以及 java 使用 JAAS 来进行 Kerberos 认证连接。本文演示为单机版。 所用软件版本 查看 Kerberos 版本命令&#xff1a;klist -V 软件名称版本jdk1.8.0_202kafka2.12-2.2.1kerberos1.15.1 1、Kerberos …

备用电源开发总结

逆变器供电 SPI 主板与LED板之前采用SPI通讯&#xff08;595驱动 30 个LED&#xff09;&#xff0c;某个LED无缘无故调动一下&#xff1b; 主板与采集板之间SPI通讯&#xff0c;采集的数据无缘无故大数据往外冒&#xff1b; 模拟量采集 采集NTC热敏电阻&#xff0c;NTC线长…

vivado 使用项目摘要、配置项目设置、仿真设置

使用项目摘要 Vivado IDE包括一个交互式项目摘要&#xff0c;可根据设计动态更新命令被运行&#xff0c;并且随着设计在设计流程中的进展。项目摘要包括概览选项卡和用户可配置的仪表板&#xff0c;如下图所示。有关信息&#xff0c;请参阅《Vivado Design Suite用户指南&…

多线程面试题目(1)

多线程基础 什么是多线程&#xff1f;多线程的优点与缺点&#xff1f; 多线程&#xff1a;多线程是指程序中包含多个执行流&#xff0c;即在一个程序中可以同时运行多个不同的线程来执行不同的任务。 优点&#xff1a;可以提高 CPU 的利用率。在多线程程序中&#xff0c;一个…

Python基础知识:整理11 模块的导入、自定义模块和安装第三方包

1 模块的导入 1.1 使用import 导入time模块&#xff0c;使用sleep功能&#xff08;函数&#xff09; import time print("start") time.sleep(3) print("end")1.2 使用from 导入time的sleep功能 from time import sleep print("start") slee…

高级分布式系统-第6讲 分布式系统的容错性--可靠的组通信

可靠的组通信 组内通信最好是每个进程之间都建立点到点的通信&#xff0c; 但实际中这样的组织结构不是有效的&#xff0c; 因为会浪费很大的通信带宽。 在平等组中&#xff0c; 多播是主要的组织结构。 但多播是具有同步性质的容错结构&#xff0c; 并不适用拜占庭模型。 多…

每日算法打卡:饮料换购 day 12

文章目录 原题链接题目描述输入格式输出格式数据范围输入样例&#xff1a;输出样例&#xff1a; 题目分析示例代码 原题链接 1216. 饮料换购 题目难度&#xff1a;简单 题目来源&#xff1a;第六届蓝桥杯省赛C A/C组,第六届蓝桥杯省赛Java B组 题目描述 乐羊羊饮料厂正在举…

LeetCode刷题笔记

面试经典150题 1. 数组/字符串 1.1 合并两个有序数组 题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺…

kotlin-运算符

区间运算符 闭区间运算符 a不能大于b var rang 1..9for(num in rang){print("${num}") //输出123456789}半开区间运算符 半开区间运算符a until b 用于定义一个从a~b(包括a边界值&#xff0c;但不包含b边界值)的所有值的区间&#xff0c;a不能大于b var rang 1 …

spring Data Elasticsearch入门

1.Elasticsearch Elasticsearch提供了两种连接方式&#xff1a; transport&#xff1a;通过TCP方式访问ES。&#xff08;已废弃&#xff09; rest&#xff1a;通过HTTP API 方式访问ES。 描述&#xff1a; Spring Data Elasticsearch 项目提供了与Elasticsearch 搜索引擎的集成…

17. 电话号码的字母组合(回溯)

从第一个数字开始遍历其对应的字母&#xff0c;将其加入StringBuffer中&#xff0c;继续深度优先搜索&#xff0c;当访问到最后一个数字的时候&#xff0c;将StringBuffer存储到ans中&#xff0c;然后回溯到下一个对应字母。 class Solution {public List<String> lette…

instanceof、对象类型转化、static关键字

instanceof 与 对象类型转换 instanceof是判断一个对象是否与一个类有关系的关键字 先看引用类型&#xff0c;再看实际类型 *例子&#xff1a;obj instanceof A 先看obj的类型是否与A有关联&#xff0c;无关联则报错&#xff0c;有关联则判断obj的实际类型 因为obj的实际类…

系分笔记数据库反规范化、SQL语句和大数据

文章目录 1、概要2、反规范化3、大数据4、SQL语句5、总结 1、概要 数据库设计是考试重点&#xff0c;常考和必考内容&#xff0c;本篇主要记录了知识点&#xff1a;反规范化、SQL语句及大数据。 2、反规范化 数据库遵循范式的设计&#xff0c;使得多表查询和连接表查询较多的时…

【面试突击】网关系统面试实战

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

基于JAVA+ssm开发的中草药智能采购管理系统设计与实现【附源码】

基于JAVAssm开发的中草药智能采购管理系统设计与实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.…

C++中的常见数据结构 --- 队列、栈、列表

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 队列、栈、列表 前言一、队列&#xff08;Queue&#xff09;二、栈&#xff08;Stack&#xff09;三、列表&#xff08;List&#xff09;总结 前言 队列、栈、列表是其中三个…

stable diffusion代码学习笔记

前言&#xff1a;本文没有太多公式推理&#xff0c;只有一些简单的公式&#xff0c;以及公式和代码的对应关系。本文仅做个人学习笔记&#xff0c;如有理解错误的地方&#xff0c;请指出。 本文包含stable diffusion入门文献和不同版本的代码。 文献资源 本文学习的代码&…

Android基于Matrix绘制PaintDrawable设置BitmapShader,以手指触点为中心显示原图像圆图,Kotlin(2)

Android基于Matrix绘制PaintDrawable设置BitmapShader&#xff0c;以手指触点为中心显示原图像圆图&#xff0c;Kotlin&#xff08;2&#xff09; 在 https://zhangphil.blog.csdn.net/article/details/135374279 基础上&#xff0c;增加一个功能&#xff0c;当手指在上面的图片…

【DevOps-08-3】Jenkins容器内部使用Docker

一、简要描述 构建镜像和发布镜像到harbor都需要使用到docker命令。而在Jenkins容器内部安装Docker官方推荐直接采用宿主机带的Docker即可。 设置Jenkins容器使用宿主机Docker。 二、配置和操作步骤 1、修改宿主机docker.sock权限 # 修改docker.sock 用户和用户组都为root $ …

并发,并行,线程与UI操作

并行和并发是计算机领域中两个相关但不同的概念。 并行&#xff08;Parallel&#xff09;指的是同时执行多个任务或操作&#xff0c;它依赖于具有多个处理单元的系统。在并行计算中&#xff0c;任务被分成多个子任务&#xff0c;并且这些子任务可以同时在不同的处理单元上执行…