D.Country Meow 最小球覆盖 三分套三分套三分 && 模拟退火
// 2019.10.3
// 练习题:2018 ICPC 南京现场赛
D Country Meow
题目大意
给定空间内 N 个点,求某个点到 N 个点的距离最大值的最小值。
思路
非常裸的最小球覆盖问题啊,即找到半径最小的球包含全部的点。
在最小圆覆盖问题上,可以使用随机增量法,这里没有四点确定球心的公式,所以板子失效了。
最小圆覆盖可以用三分套三分,这里空间有三维,假装证明得到在任意一维上都满足凸函数特性,那么再套一层维度三分就OK了。
AC代码
三分套三分套三分写法,复杂度O(n*log^3)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-3;
struct Point {
double x, y, z;
Point() {
x = y = z = 0.0;
}
Point(double xx, double yy, double zz) {
x = xx, y = yy, z = zz;
}
Point operator-(const Point& p) {
return Point(x-p.x, y-p.y, z-p.z);
}
double dis() {
return sqrt(x*x+y*y+z*z);
}
}pt[110];
int n;
double cal(double x, double y, double z) {
double res = 0;
for(int i=1;i<=n;i++) {
res = max(res, (pt[i]-Point(x, y, z)).dis());
}
return res;
}
double cal2(double x, double y) {
double res = 1e18;
double l = -100000, r = 100000;
while(r-l>eps) {
double m1 = (r-l)/3 + l;
double m2 = (r-l)/3*2 + l;
double res1 = cal(x, y, m1), res2 = cal(x, y, m2);
res = min(res, min(res1, res2));
if(res1<res2) r = m2;
else l = m1;
}
return res;
}
double cal3(double x) {
double res = 1e18;
double l = -100000, r = 100000;
while(r-l>eps) {
double m1 = (r-l)/3 + l;
double m2 = (r-l)/3*2 + l;
double res1 = cal2(x, m1), res2 = cal2(x, m2);
res = min(res, min(res1, res2));
if(res1<res2) r = m2;
else l = m1;
}
return res;
}
int main() {
cin>>n;
for(int i=1;i<=n;i++) {
scanf("%lf %lf %lf", &pt[i].x, &pt[i].y, &pt[i].z);
}
double res = 1e18;
double l = -100000, r = 100000;
while(r-l>eps) {
double m1 = (r-l)/3 + l;
double m2 = (r-l)/3*2 + l;
double res1 = cal3(m1), res2 = cal3(m2);
res = min(res, min(res1, res2));
if(res1<res2) r = m2;
else l = m1;
}
printf("%.10lf\n", res);
return 0;
}
模拟退火写法,对于三维复杂度更低:
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-5;
struct Point{
double x, y, z;
}p[110], op;
int n;
inline double dist(Point &a, Point &b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}
void solve() {
double ans, delta = 10000.0;
double maxDis, tempDis;
while(delta>eps){
int id = 0;
maxDis = dist(op, p[id]);
for(int i=1;i<n;i++){
tempDis=dist(op,p[i]);
if(tempDis>maxDis){
maxDis = tempDis;
id = i;
}
}
ans = maxDis;
op.x += (p[id].x-op.x)/maxDis*delta;
op.y += (p[id].y-op.y)/maxDis*delta;
op.z += (p[id].z-op.z)/maxDis*delta;
delta *= 0.98;
}
printf("%.10lf\n", ans);
}
int main() {
while(scanf("%d", &n)!=EOF && n) {
op.x = op.y = op.z = 0;
for(int i=0;i<n;i++) {
scanf("%lf %lf %lf", &p[i].x, &p[i].y, &p[i].z);
}
solve();
}
return 0;
}
POJ2069 Super Star
这一题三分做法会T,只能用模拟退火才能过。
注意初始点选择。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-5;
struct Point{
double x, y, z;
}p[35], op;
int n;
inline double dist(Point &a, Point &b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}
void solve() {
double ans, delta = 100.0;
double maxDis, tempDis;
while(delta>eps){
int id = 0;
maxDis = dist(op, p[id]);
for(int i=1;i<n;i++){
tempDis=dist(op,p[i]);
if(tempDis>maxDis){
maxDis = tempDis;
id = i;
}
}
ans = maxDis;
op.x += (p[id].x-op.x)/maxDis*delta;
op.y += (p[id].y-op.y)/maxDis*delta;
op.z += (p[id].z-op.z)/maxDis*delta;
delta *= 0.98;
}
printf("%.5lf\n", ans);
}
int main() {
while(scanf("%d", &n)!=EOF && n) {
op.x = op.y = op.z = 0;
for(int i=0;i<n;i++) {
scanf("%lf %lf %lf", &p[i].x, &p[i].y, &p[i].z);
op.x += p[i].x;
op.y += p[i].y;
op.z += p[i].z;
}
op.x /= n; op.y /= n; op.z /= n;
solve();
}
return 0;
}
HDU3007 HDU3932 类似。
注意HDU3932 n==1采用模拟退火要特判。。。。
D.Country Meow 最小球覆盖 三分套三分套三分 && 模拟退火的更多相关文章
- Gym - 101981D The 2018 ICPC Asia Nanjing Regional Contest D.Country Meow 最小球覆盖
题面 题意:给你100个三维空间里的点,让你求一个点,使得他到所有点距离最大的值最小,也就是让你找一个最小的球覆盖掉这n个点 题解:红书模板题,这题也因为数据小,精度也不高,所以也可以用随机算法,模拟 ...
- 最小球覆盖——模拟退火&&三分套三分套三分
题目 给出 $N(1 \leq N \leq 100)$ 个点的坐标 $x_i,y_i,z_i$($-100000 \leq x_i,y_i,z_i \leq 100000$),求包围全部点的最小的球 ...
- Gym101981D - 2018ACM-ICPC南京现场赛D题 Country Meow
2018ACM-ICPC南京现场赛D题-Country Meow Problem D. Country Meow Input file: standard input Output file: sta ...
- 2018ICPC南京D. Country Meow
题目: 题意:三维里有n个点,找一个最小的球将所有点覆盖. 题解:退火法模拟的一道板子题. 1 #include <stdio.h> 2 #include <iostream> ...
- Super Star(最小球覆盖)
Super Star http://poj.org/problem?id=2069 Time Limit: 1000MS Memory Limit: 65536K Total Submission ...
- Country Meow
Country Meow 和这基本一样 https://www.cnblogs.com/Fighting-sh/p/9809518.html #include<iostream> #inc ...
- POJ 最小球覆盖 模拟退火
最小球覆盖:用半径最小的球去覆盖所有点. 纯粹的退火算法,是搞不定的,精度不够,不然就会TLE,根本跑不出答案来. 任取一点为球心,然后一点点靠近最远点.其实这才是最主要的. 因为:4个点确定一个球, ...
- Gym - 101981D Country Meow(模拟退火)
题意 三维空间有\(n\)个点,找到另外一个点,离所有点的最大距离最小.求这个距离. 题解 \(1\).最小球覆盖,要找的点为球心. \(2\).模拟退火. 还是补一下模拟退火的介绍吧. 模拟退火有一 ...
- POJ2069 最小球覆盖 几何法和退火法
对这种问题不熟悉的读者 可以先去看一看最小圆覆盖的问题 ZOJ1450 现在我们来看最小球覆盖问题POJ2069 题目很裸,给30个点 求能覆盖所有点的最小球的半径. 先给出以下几个事实: 1.对于一 ...
随机推荐
- js 读取本地文件(必须通过input控件才能实现) 及 下载文件
js 操作 文件的实现原理: 1.js是不能直接操作(读写)文件的,html的 input[type="file"] 控件是可以读取文件数据(获取文件数据流)的.js可以获取这个 ...
- linux R环境安装以及注意事项
安装Ryum install Ryum install readline-develyum install libXt-devel 1.安装后在R命令行启动Rserve,在脚本中不要重复加载Rserv ...
- CSS:CSS 表格
ylbtech-CSS:CSS 表格 1.返回顶部 1. CSS 表格 使用 CSS 可以使 HTML 表格更美观. Company Contact Country Alfreds Futterkis ...
- c# 使用 java的 rsa 进行签名
/// <summary> /// 类名:RSAFromPkcs8 /// 功能:RSA加密.解密.签名.验签 /// 详细:该类对Java生成的密钥进行解密和签名以及验签专用类,不需要修 ...
- PHP-FPM 远程代码执行漏洞(CVE-2019-11043)复现-含EXP
搭建容器 安装golang 利用程序 https://github.com/neex/phuip-fpizdam 安装git Cobra包安装 go get -v github.com/spf13/c ...
- 【转载】Spring 源码分析之 bean 实例化原理
本次主要想写spring bean的实例化相关的内容.创建spring bean 实例是spring bean 生命周期的第一阶段.bean 的生命周期主要有如下几个步骤: 创建bean的实例 给实例 ...
- C#WinForm 窗体回车替换Tab
/// <summary> /// 回车切换控件 /// </summary> /// <param name="sender"></pa ...
- CSS 案例学习
1.样式 display:inline-block;可改变a标签,合其可定义宽高 2.a:hover表示鼠标经过 3.background:url(110.png) bottom 表示:给链接一个图片 ...
- Codeforces346D. Robot Control
D. Robot Control time limit per test 6 seconds memory limit per test 256 megabytes input standard in ...
- final、finally和finalized的区别?
(1)final:被final修饰的类,不被能继承:被final修饰的方法,不能被重写:被fianl修饰的量,为常量,只能被赋值一次: (2)finally:异常处理,和try.catch结合使用,可 ...