// 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 最小球覆盖 三分套三分套三分 && 模拟退火的更多相关文章

  1. Gym - 101981D The 2018 ICPC Asia Nanjing Regional Contest D.Country Meow 最小球覆盖

    题面 题意:给你100个三维空间里的点,让你求一个点,使得他到所有点距离最大的值最小,也就是让你找一个最小的球覆盖掉这n个点 题解:红书模板题,这题也因为数据小,精度也不高,所以也可以用随机算法,模拟 ...

  2. 最小球覆盖——模拟退火&&三分套三分套三分

    题目 给出 $N(1 \leq N \leq 100)$ 个点的坐标 $x_i,y_i,z_i$($-100000 \leq x_i,y_i,z_i \leq 100000$),求包围全部点的最小的球 ...

  3. Gym101981D - 2018ACM-ICPC南京现场赛D题 Country Meow

    2018ACM-ICPC南京现场赛D题-Country Meow Problem D. Country Meow Input file: standard input Output file: sta ...

  4. 2018ICPC南京D. Country Meow

    题目: 题意:三维里有n个点,找一个最小的球将所有点覆盖. 题解:退火法模拟的一道板子题. 1 #include <stdio.h> 2 #include <iostream> ...

  5. Super Star(最小球覆盖)

    Super Star http://poj.org/problem?id=2069 Time Limit: 1000MS   Memory Limit: 65536K Total Submission ...

  6. Country Meow

    Country Meow 和这基本一样 https://www.cnblogs.com/Fighting-sh/p/9809518.html #include<iostream> #inc ...

  7. POJ 最小球覆盖 模拟退火

    最小球覆盖:用半径最小的球去覆盖所有点. 纯粹的退火算法,是搞不定的,精度不够,不然就会TLE,根本跑不出答案来. 任取一点为球心,然后一点点靠近最远点.其实这才是最主要的. 因为:4个点确定一个球, ...

  8. Gym - 101981D Country Meow(模拟退火)

    题意 三维空间有\(n\)个点,找到另外一个点,离所有点的最大距离最小.求这个距离. 题解 \(1\).最小球覆盖,要找的点为球心. \(2\).模拟退火. 还是补一下模拟退火的介绍吧. 模拟退火有一 ...

  9. POJ2069 最小球覆盖 几何法和退火法

    对这种问题不熟悉的读者 可以先去看一看最小圆覆盖的问题 ZOJ1450 现在我们来看最小球覆盖问题POJ2069 题目很裸,给30个点 求能覆盖所有点的最小球的半径. 先给出以下几个事实: 1.对于一 ...

随机推荐

  1. Service4

    DNS解析的作用• 为什么需要DNS系统– www.baidu.com 与 119.75.217.56,哪个更好记?– 互联网中的114查号台/导航员 • DNS服务器的功能– 正向解析:根据注册的域 ...

  2. flutter 卡在Running Gradle task 'assembleDebug'...

    Android项目运行时出错 卡在Initializing gradle… 运行时会卡在Initializing gradle..., 此时因为Android项目会用到Gradle, 如果没有FQ,下 ...

  3. Python100天打卡-Day10

    实现动画效果要实现动画效果,本身的原理也非常简单,就是将不连续的图片连续的播放,只要每秒钟达到了一定的帧数,那么就可以做出比较流畅的动画效果.import pygame def main(): # 初 ...

  4. 用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy

    目录 目录 前文列表 扩展阅读 前言 Models 模型 SQLAlchemy 安装 SQLAlchemy 安装 Mysql 建立 SQLAlchemy 和 Mysql 的连接 前文列表 用 Flas ...

  5. D题 Robots 【期望】

    Robots Given a directed graph with no loops which starts at node 11 and ends at node nn.There is a r ...

  6. 关于py中lxml模块的cssselect的小问题

    今天在使用lxml进行解析页面的时候遇到了不能解析空格的问题,就是类似于: <div class="aa bb"></div> 使用cssselect('. ...

  7. Alice's Classified Message HDU - 5558 后缀自动机求某个后缀出现的最早位置

    题意: 给定一个长度不超过 10W 的只包含小写字母的字符串,从下标 0 到 n−1.从下标 0 开始操作, 每次对于下标 pos查找下标 pos 开始的子串中最长的在其他地方出现过的长度,其他出现的 ...

  8. 一键抓取Android的Locat Log

    很多小伙伴在做App测试时,一遇到Cash,开发同学最常说的一句话,就是抓下Locat日志,很多小伙伴一听到这个抓取日志就会觉得有点烦. ​主要有2点: ​    ​    ​1.是这个bug可能不好 ...

  9. D3.js 区域生成器 (V3版本)

    区域生成器(Area Generator)   区域生成器(Area Generator)用于生成一块区域,使用方法与线段生成器类似.线段生成器地址:数据访问器有x().x0().x1().y().y ...

  10. WdatePicker设置时间与倒计时

    之前苦于jQuery的datetimepicker插件不知道如何设置秒数,用了同学推荐的WdatePicker,真心好用. 相关文档用法可以上http://www.my97.net/dp/index. ...