[Balkan2002][Alien最小圆覆盖][随机增量法]
时间:2011-03-04 来源:ch_g
ZOJ 1450 和 HDU 3007都是最小圆覆盖的题目,不过规模比起http://61.187.179.132:8080/JudgeOnline/showproblem?problem_id=1336
这个OJ上的真是小巫见大巫了。
/*
题目:Alien最小圆覆盖
题目来源:Balkan2002
http://61.187.179.132:8080/JudgeOnline/showproblem?problem_id=1336
题目难度:中等
题目内容或思路:
随机增量法 + 最小圆覆盖
做题日期:2011.3.4
*/
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <vector>
#include <bitset>
#include <cmath>
#include <set>
#include <utility>
#include <ctime>
using namespace std;
const int N = 100010;
const double eps = 1e-12;
int n;
struct cpoint {
double x, y;
}cp[N];
int dcmp(double x) {
if (x < -eps) return -1; else return x > eps;
}
double sqr(double x) { return x * x; }
double dis(cpoint p1, cpoint p2) {
return sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y));
}
void center(cpoint p0, cpoint p1, cpoint p2, cpoint &cp) { //三角形外心
double a1=p1.x-p0.x, b1=p1.y-p0.y, c1=(sqr(a1)+sqr(b1))/2;
double a2=p2.x-p0.x, b2=p2.y-p0.y, c2=(sqr(a2)+sqr(b2))/2;
double d = a1 * b2 - a2 * b1;
cp.x = p0.x + (c1 * b2 - c2 * b1) / d;
cp.y = p0.y + (a1 * c2 - a2 * c1) / d;
}
void MinCir(cpoint cp[], int n, cpoint &c, double &r) {
random_shuffle(cp, cp + n);
c = cp[0]; r = 0;
for (int i = 1; i < n; ++i) {
if (dcmp(dis(cp[i], c) - r) <= 0) continue;
c = cp[i]; r = 0;
for (int j = 0; j < i; ++j) {
if (dcmp(dis(cp[j], c) - r) <= 0) continue;
c.x = (cp[i].x + cp[j].x) / 2;
c.y = (cp[i].y + cp[j].y) / 2;
r = dis(c, cp[j]);
for (int k = 0; k < j; ++k) {
if (dcmp(dis(cp[k], c) - r) <= 0) continue;
center(cp[i], cp[j], cp[k], c);
r = dis(c, cp[k]);
}
}
}
}
void solve() {
for (int i = 0; i < n; ++i) {
scanf("%lf%lf", &cp[i].x, &cp[i].y);
}
cpoint c;
double r;
MinCir(cp, n, c, r);
printf("%.10lf\n%.10lf %.10lf\n", r, c.x, c.y);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("D:\\in.txt", "r", stdin);
#endif
while (scanf("%d", &n) != EOF) {
solve();
}
return 0;
}
相关阅读 更多 +