// 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. 表格排序tablesort小案列

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  2. express简易代理请求

    var express = require('express') var app = express() var proxy = require('http-proxy-middleware') va ...

  3. linux find相关 (持续更新中)

    按名字查找 find . -name *.txt find . -name test* # . 指的是当前路径, 查找全局的话把. 换成/ 查找并删除多个文件 find -type f -name & ...

  4. org.apache.hadoop.hbase.master.HMasterCommandLine: Master exiting java.lang.RuntimeException: HMaster Aborted

    前一篇的问题解决了,是 hbase 下面lib 包的jar问题,之前写MR的时候加错了包,替换掉了原来的包后出现另一问题:@ubuntu:/home/hadoop/hbase-0.94.6-cdh4. ...

  5. CF#538 C - Trailing Loves (or L'oeufs?) /// 分解质因数

    题目大意: 求n!在b进制下末尾有多少个0 https://blog.csdn.net/qq_40679299/article/details/81167283 一个数在十进制下末尾0的个数取决于10 ...

  6. hdu6350 /// tarjan+并查集+组合+最大流思想

    题目大意: 给定n个点 m条边没有重边的仙人掌图(没有一条边会同时存在与两个环 也就是环都是相互独立的) 求任意两点间 i^j^maxflow(i,j)的总和 maxflow为两点间最大流 题解:ht ...

  7. 怎样有效防止ddos

    怎样有效防止ddos?当我们发现服务器被DDoS攻击的时候,不要过度惊慌失措,先查看一下网站服务器是不是被黑了,找出网站存在的黑链,然后做好网站的安全防御,开启IP禁PING,可以防止被扫描,关闭不需 ...

  8. JQuery on绑定click无效的的bug解决办法?

    如果你在移动端使用zepto.js, touch 来代替click事件,那就没有上述标题的问题了.如果你仍然使用了click,在点击事件中苹果机就可能出现无效的结果. 第一种方法: 解决的方法很巧妙, ...

  9. GitHub上传项目之初体验

    git工具是很早之前安装的,之前还没有github账号,现在注册了一个,想学一下托管自己的项目和代码. 登录github账号之后,点击绿色的"New repository",输入名 ...

  10. BIO、NIO和AIO

    BIO(Blocking I/O)同步阻塞I/O 这是最基本与简单的I/O操作方式,其根本特性是做完一件事再去做另一件事,一件事一定要等前一件事做完,这很符合程序员传统的顺序来开发思想,因此BIO模型 ...