HDU-4454 Stealing a Cake 三分枚举

题意:给定一个点,一个圆,以及一个矩形,现在问从一个点到一个圆再到一个矩形的最短距离为多少?到达一个目标可以只挨着或者穿过它。

解法:目前只知道从一个点到圆上按照[0,PI],[PI,2*PI]的两个半圆进行划分确实是满足距离是一个凹函数,但是加上到矩形的距离后仍然满足三分性质则不知道怎么得到的。具体做法是先将整个坐标系平移使得圆心落在(0, 0)处,然后三分枚举圆上的点,距离由两部分组成,一部分是点到圆上点的距离,一部分是点到矩形的距离,后者转化为点到四条线段的距离求解。

代码如下:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;const double eps = 1e-6;
const double PI = acos(-1.0);
double cx, cy, cr; // 圆的圆心以及半径

inline int sign(double x) {return x < -eps ? -1 : x > eps ? 1 : 0;
}struct Point {double x, y;Point (double xx = 0, double yy = 0) : x(xx), y(yy) {}Point operator - (const Point &ot) const { // 两个点作差获得向量 return Point(x - ot.x , y - ot.y);}double operator * (const Point &ot) const { // 重载点积return x * ot.x + y * ot.y;}double operator ^ (const Point &ot) const { // 重载叉积 return x * ot.y - y * ot.x;}bool operator < (const Point &ot) const {if (sign(x - ot.x)) {return sign(x - ot.x) < 0; // 首先按照横坐标排序 } else { // 然后按照纵坐标排序 return sign(y - ot.y) < 0;}}void show() {printf("x = %.2f, y = %.2f\n", x, y);}
};Point it, rp[4];double dist(const Point &a, const Point &b) {return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}double dtoL(const Point &np, const Point &st, const Point &ed) { // 点到线段的距离 double ret; if (sign((ed-st)*(np-st)) > 0 && sign((st-ed)*(np-ed) > 0)) { // 用来判定一个该点的投影在该线段上ret = fabs((st-np)^(ed-np)) / dist(st, ed);} else {ret = min(dist(np, st), dist(np, ed)); // 点到两个端点的较小值
    }return ret;
}double dtoR(const Point &np) { // 到四条线段的最短距离 double d1 = min(dtoL(np, rp[0], rp[1]), dtoL(np, rp[0], rp[2]));double d2 = min(dtoL(np, rp[1], rp[3]), dtoL(np, rp[2], rp[3]));return min(d1, d2);
}double tsearch(double l, double r) {double delta;while (r - l >= eps) {delta = (r - l) / 3.0; // delta表示是区间长度的1/3Point Lp(cr*cos(l+delta), cr*sin(l+delta));Point Rp(cr*cos(r-delta), cr*sin(r-delta));double d1 = dist(it, Lp) + dtoR(Lp);double d2 = dist(it, Rp) + dtoR(Rp);if (sign(d1 - d2) > 0) {l += delta;} else {r -= delta;}}Point fp(cr*cos(r), cr*sin(r));return dist(it, fp) + dtoR(fp);
}void solve() {// 先三分[0, PI],在三分[PI, 2*PI]内的角度printf("%.2f\n", min(tsearch(0, PI), tsearch(PI, 2*PI)));
}int main() {while (scanf("%lf %lf", &it.x, &it.y), sign(it.x) | sign(it.y)) {scanf("%lf %lf %lf", &cx, &cy, &cr); // 读取圆心坐标和半径it.x -= cx, it.y -= cy;              // 将圆心平移到源点,其余坐标均作出改变scanf("%lf %lf", &rp[0].x, &rp[0].y);rp[0].x -= cx, rp[0].y -= cy;scanf("%lf %lf", &rp[1].x, &rp[1].y);rp[1].x -= cx, rp[1].y -= cy;rp[2].x = rp[0].x, rp[2].y = rp[1].y;rp[3].x = rp[1].x, rp[3].y = rp[0].y;sort(rp, rp+4); // 获得矩形的四个顶点,并排序,方便得到线段与点的关系double t = sqrt(2.0) / 2;solve();}return 0;
}

 

转载于:https://www.cnblogs.com/Lyush/archive/2013/05/30/3108485.html

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

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

相关文章

VIP - virtual IP address

virtual IP address (虚拟 IP 地址)1、是集群的ip地址&#xff0c;一个vip对应多个机器2、与群集关联的唯一 IP 地址see wiki&#xff1a; A virtual IP address (VIP or VIPA) is an IP address assigned to multiple applications residing on a single server, multiple dom…

linux上perl怎么传输参数,如何在perl子函数中传递参数?

慕村225694Perl 可以通过函数元型在编译期进行有限的参数类型检验。如果你声明sub mypush ()那么 mypush() 对参数的处理就同内置的 push() 完全一样了。函数声明必须要在编译相应函数调用之前告知编译器(编译器在编译函数调用时会对相应函数用 prototype来查询它的元型来进行参…

Android中级之网络数据解析一之Json解析

本文来自http://blog.csdn.net/liuxian13183/ &#xff0c;引用必须注明出处&#xff01; 在网络传输的时候&#xff0c;经常用到的解析方式有xml和json两种&#xff0c;今天我们主要来说下json、解析&#xff0c;以及其要点。 首先json格式&#xff1a; “[”标识json解析开始…

Struts2中ValueStack结构和总结

【ValueStack和ActionContext的关系】首先&#xff0c;从结构上来看ValueStack是ActionContext的一个组成部分&#xff0c;是对ActionContext功能的扩展。ActionContext是一个容器结构&#xff0c;是Struts2中用于数据存储的的场所&#xff0c;而ValueStack则是一个具备表达式引…

将USB-WiFi网卡移植到X210开发板

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、移植前的准备工作 1、搭建开发环境 &#xff08;1&#xff09;虚拟机运行着ubuntu14.04系统。 &#xff08;2&#xff09;X210开发板运行着linux内核镜像、QT4.8文件系统镜像。相关的镜像文件在…

文件读取ini文件另一种读取办法

时间紧张&#xff0c;先记一笔&#xff0c;后续优化与完善。 Windows下的ini文件的读取可以应用系统提供的api来实现 GetPrivateProfileString GetPrivateProfileInt ... 现实应用中, 如果不应用一种同一的方法来包装一下会让源代码看起来很乱。 所以,须要计划一个便利&#xf…

浅谈mysql数据库引擎

2019独角兽企业重金招聘Python工程师标准>>> 数据库是数据的集合&#xff0c;计算机中的数据库是存储器上一些文件的集合或者是内存数据的集合。Mysql,SQL server数据库都是可以存储数据&#xff0c;并提供数据查询&#xff0c;更新功能的数据库管理系统。Mysql数据…

网络摄像机简介

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 一、网络摄像机定义 &#xff08;1&#xff09;网络摄像机&#xff0c;也叫IP摄像机&#xff0c;即IPCamera&#xff0c;简称IPC&#xff0c;近几年得益于网络带宽&#xff0c;芯片技术&#xff0c;算法技术…

如今的移动操作系统,写在2013年——android篇 by 伊一线天

前奏&#xff1a; 曾在2011年&#xff0c;我写过一篇同样题材的文章。时隔2年后&#xff0c;如今的移动操作系统领域跌宕起伏&#xff0c;2年前的一些系统变得更加强大&#xff0c;一些已经昙花一现。现在让我再来总结一些2013年移动操作系统。 第一讲&#xff1a;android 自从…

linux qt ping,Qt5.2中使用ping命令实现Ip扫描功能

在实现类似于Free IP Scanner 2.1的Ip扫描器软件中&#xff0c;会用到ping命令。如果使用Qt编程实现&#xff0c;主要会用QThread、QProcess这两个类。关于这两个类的具体用法可以查阅Qt助手或者QT官网。在QT中为了扫描大量的Ip&#xff0c;通常需要将扫描Ip的任务放在一个单独…

Python安装模块出错(ImportError: No module named setuptools)解决方法

原地址&#xff1a;http://www.cnblogs.com/BeginMan/archive/2013/05/28/3104928.html 在window平台下安装第三方模块时&#xff0c;出现这样的错误&#xff1a; Google了以下&#xff0c;才知道原来Python里少了这个模块。 我们可以在Python官网去查找 其中 Package Index中查…

kali linux 2.0 ssh,Kali 2.0使用SSH进行远程登录(示例代码)

一、配置SSH参数修改sshd_config文件&#xff0c;命令为&#xff1a;vim /etc/ssh/sshd_config将#PasswordAuthentication no的注释去掉&#xff0c;并且将NO修改为YES //kali中默认是yes将PermitRootLogin without-password修改为PermitRootLogin yes二、启动SSH服务命令为&am…

数据库课程设计报告

课程设计报告内容 封面&#xff08;注明组员及分工&#xff09; 目录 1&#xff0e;系统概述 – 系统的特点 – 系统设计环境 2&#xff0e;系统需求分析 – 系统设计的目标 – 系统需求分析&#xff08;给出&#xff1a;数据流图、数据字典&#xff09; – 系统功能…

基于Hi3516A的H265 IPC LIVE555 开发

转载于http://m.blog.csdn.net/faihung/article/details/73008742&#xff0c;如有侵权请告知删除。 1 系统工作原理 系统以Hi3516A开发平台&#xff08;由高分辨率1080 p的AR0330摄像头模块、带千兆以太网功能的Hi3516A控制器模块组成硬件平台&#xff0c;并在硬件平台上烧写了…

教材配套PPT初稿

1&#xff0d;10章初稿&#xff0c;基本完整。有些粗糙&#xff0c;后面可能会稍作调整。 附更新情况如下&#xff1a; 1.增加了第10章内容&#xff1b; 2.第5章增加了一些内容&#xff1b; 3.第3章内容部分更新&#xff1b; 4.增加了第8&#xff0d;9章内容。 订正&#xff1a…

linux ssh抓包,如何在SSH连接Linux系统的环境下使用wireshark抓包?

TSINGSEE青犀视频云边端架构EasyNVR、EasyDSS、EasyGBS等都是有两种操作系统的版本&#xff0c;一种是linux&#xff0c;一种是windows。而大多数开发者用户都会使用linux版本进行安装。对于安装部署出现的问题&#xff0c;TSINGSEE青犀视频团队研发的经常为客户远程调试&#…

Gearman 启动日志文件提示协议出错的BUG

如果直接以gearmand -d 启动 /usr/local/var/log/gearmand.log 里提示 Address family not supported by protocol ERROR 2014-11-20 20:05:49.000000 [ main ] socket()(Address family not supported by protocol) -> libgearman-server/gearmand.cc:468 ERROR 2014-11-20…

linux环境变量设置方法(PATH等环境变量)

以下内容源于网络资源的学习与整理&#xff0c;如有侵权请告知删除。 linux系统的环境变量有很多&#xff0c;这里简单介绍几个常见环境变量的设置方法。 环境变量PATH 这个环境变量&#xff0c;表示“可执行程序的查找路径”。 1、查看PATH的值&#xff0c;输入“echo $PATH”…

ASP.NET后台调用前台JS函数的三种常见方法

为什么80%的码农都做不了架构师&#xff1f;>>> 第一种&#xff1a;使用普通的添加控件中的Attributes属性进行调用 例如&#xff0c;像一般的普通的按钮&#xff1a;Button1.Attributes.Add("onclick","MyFun();"); 此方法只能在Onload中或者…