BZOJ 1336 Balkan2002 Alien最小圆覆盖

题目大意:最小圆覆盖。

思路:再拍一份模板。做法见:http://blog.csdn.net/jiangyuze831/article/details/43950601

CODE:

#define _CRT_SECURE_NO_WARNINGS

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define MAX 100010
using namespace std;

struct Point{
	double x,y;

	Point(double _,double __):x(_),y(__) {}
	Point() {}
	Point operator +(const Point &a)const {
		return Point(x + a.x,y + a.y);
	}
	Point operator -(const Point &a)const {
		return Point(x - a.x,y - a.y);
	}
	Point operator *(double a)const {
		return Point(x * a,y * a);
	}
	void Read() {
		scanf("%lf%lf",&x,&y);
	}
}point[MAX];

inline double Cross(const Point &p1,const Point &p2)
{
	return p1.x * p2.y - p1.y * p2.x;
}

inline double Calc(const Point &p1,const Point &p2)
{
	return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}

inline Point Mid(const Point &p1,const Point &p2)
{
	return Point((p1.x + p2.x) / 2,(p1.y + p2.y) / 2);
}

inline Point Change(const Point &v)
{
	return Point(-v.y,v.x);
}

struct Circle{
	Point o;
	double r;

	Circle(const Point &_,double __):o(_),r(__) {}
	Circle() {}
	bool InCircle(const Point &p) {
		return Calc(o,p) <= r;
	}
};

struct Line{
	Point p,v;

	Line(const Point &_,const Point &__):p(_),v(__) {}
	Line() {}
};

inline Point GetIntersection(const Line &l1,const Line &l2)
{
	Point u = l1.p - l2.p;
	double t = Cross(l2.v,u) / Cross(l1.v,l2.v);
	return l1.p + l1.v * t;
}

int points;

int main()
{
	cin >> points;
	for(int i = 1; i <= points; ++i)
		point[i].Read();
	random_shuffle(point + 1,point + points + 1);
	Circle now(point[1],.0);
	for(int i = 2; i <= points; ++i)
		if(!now.InCircle(point[i])) {
			now = Circle(point[i],.0);
			for(int j = 1; j < i; ++j)
				if(!now.InCircle(point[j])) {
					now = Circle(Mid(point[i],point[j]),Calc(point[i],point[j]) / 2);
					for(int k = 1; k < j; ++k)
						if(!now.InCircle(point[k])) {
							Line l1(Mid(point[i],point[j]),Change(point[j] - point[i]));
							Line l2(Mid(point[j],point[k]),Change(point[k] - point[j]));
							Point intersection = GetIntersection(l1,l2);
							now = Circle(intersection,Calc(intersection,point[i]));
						}
				}
		}
	cout << fixed << setprecision(10) << now.r << '\n' << now.o.x << ' ' << now.o.y << endl;
	return 0;
}

时间: 2024-10-16 05:15:01

BZOJ 1336 Balkan2002 Alien最小圆覆盖的相关文章

BZOJ 1336 Balkan2002 Alien最小圆覆盖 随机增量法

题目大意:求最小圆覆盖 随机增量法裸题 注意多输出几位小数不然过不去= = #include <cmath> #include <cstdio> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define M 100100 #define EPS 1e-7 using namespace std; struct Point

Bzoj 1336&amp;1337 Alien最小圆覆盖

1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 Sec  Memory Limit: 162 MBSec  Special Judge Submit: 1473  Solved: 648 [Submit][Status][Discuss] Description Input 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000.0) Output Sample Input 6 8.0

bzoj2823: [AHOI2012]信号塔&amp;&amp;1336: [Balkan2002]Alien最小圆覆盖&amp;&amp;1337: 最小圆覆盖

首先我写了个凸包就溜了 这是最小圆覆盖问题,今晚学了一下 先随机化点,一个个加入 假设当前圆心为o,半径为r,加入的点为i 若i不在圆里面,令圆心为i,半径为0 再重新从1~i-1不停找j不在圆里面,令圆心为ij中点,直径为ij距离 再重新在1~j-1不停找k不在圆里面,三点可确定一圆,初中数学 复杂度看似O(n^3)实则O(n),好玄学 坑点:注意如果用点斜式表示方程有斜率为不存在的情况,需要特判 #include<cstdio> #include<iostream> #incl

【BZOJ1336】[Balkan2002]Alien最小圆覆盖 随机增量法

[BZOJ1336][Balkan2002]Alien最小圆覆盖 Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000.0) Output 输出圆的半径,及圆心的坐标 Sample Input 6 8.0 9.0 4.0 7.5 1.0 2.0 5.1 8.7 9.0 2.0 4.5 1.0 Sample Output 5.00 5.00 5

【bzoj1336/1337/2823】[Balkan2002]Alien最小圆覆盖 随机增量法

题目描述 给出N个点,让你画一个最小的包含所有点的圆. 输入 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000.0) 输出 输出圆的半径,及圆心的坐标 样例输入 6 8.0 9.0 4.0 7.5 1.0 2.0 5.1 8.7 9.0 2.0 4.5 1.0 样例输出 5.00 5.00 5.00 题解 随机增量法求最小圆覆盖裸题 求法:设初始圆为某空圆,先枚举第一个点,如果不在当前圆内,则令当前圆为这一个点的最小圆

[bzoj1336] [Balkan2002]Alien最小圆覆盖

最小圆覆盖..三个for是O(n)的QAQ..因为随机化后新的点不在当前圆内的几率不大.. 学习了下求中垂线的姿势... 1 #include<cstdio> 2 #include<cmath> 3 #include<iostream> 4 #include<cstdlib> 5 #include<algorithm> 6 #define d double 7 using namespace std; 8 const int maxn=1e5+2

【BZOJ-1336&amp;1337】Alie最小圆覆盖 最小圆覆盖(随机增量法)

1336: [Balkan2002]Alien最小圆覆盖 Time Limit: 1 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1573  Solved: 697[Submit][Status][Discuss] Description 给出N个点,让你画一个最小的包含所有点的圆. Input 先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000.0) Outpu

[BZOJ 3564] [SHOI2014] 信号增幅仪 【最小圆覆盖】

题目链接:BZOJ - 3564 题目分析 求最小椭圆覆盖,题目给定了椭圆的长轴与 x 轴正方向的夹角,给定了椭圆长轴与短轴的比值. 那么先将所有点旋转一个角度,使椭圆长轴与 x 轴平行,再将所有点的 x 坐标除以长轴与短轴的比值,然后就直接做最小圆覆盖了. 随机增量法,一定别忘了 random_shuffle . 代码 #include <iostream> #include <cstdlib> #include <cstring> #include <cstd

bzoj 1337 最小圆覆盖

bzoj 1337 最小圆覆盖 补充一个求三角形外心的向量法.用了点积的几何意义,很实用.出处. 使用随机增量法求.首先随机打乱顺序,然后三重循环,选择当前在圆外的点更新圆,分别按照 \(1/2/3\) 个点确定圆的方式更新即可. 由于随机一个点不在前 \(i\) 个点的最小覆盖圆内的概率是 \(\frac 3 i\) ,可以证明这样的时间复杂度是 \(O(n)\) 的,这种做法可以推广到常数维度上,时间复杂度仍为 \(O(n)\) . #include<bits/stdc++.h> usin