circle minCircle(point P[], int N) { // `1-based`
	if (N == 1) return circle(P[1], 0.0);
	random_shuffle(P + 1, P + N + 1);
	circle O = minCircle(P[1], P[2]);
	Rep(i, 1, N) if(!O.inside(P[i])) { O = minCircle(P[1], P[i]);
		Foru(j, 1, i) if(!O.inside(P[j])) { O = minCircle(P[i], P[j]);
			Foru(k, 1, j) if(!O.inside(P[k])) O = minCircle(P[i], P[j], P[k]);
		}
예제 #2
0
inline static std::pair<std::pair<long double, long double>, long double> findCircle(unsigned int s, unsigned int e)
{
	for(unsigned int p = s; p < e; ++ p)
		sPoint[p] = point[p];

	return minCircle(s, e);
}
예제 #3
0
inline static std::pair<std::pair<long double, long double>, long double> minCircle(unsigned int s, unsigned int e, int q1, int q2, int q3)
{
	std::pair<std::pair<long double, long double>, long double> res;
	std::random_shuffle(sPoint + s, sPoint + e);
	if(q3 != -1) // GOT A TRIPLE
	{
		res.first.first = ((sPoint[q2].first * sPoint[q2].first * sPoint[q3].second + sPoint[q2].second * sPoint[q2].second * sPoint[q3].second - sPoint[q1].first * sPoint[q1].first * sPoint[q3].second + sPoint[q1].first * sPoint[q1].first * sPoint[q2].second - sPoint[q1].second * sPoint[q1].second * sPoint[q3].second + sPoint[q1].second * sPoint[q1].second * sPoint[q2].second + sPoint[q1].second * sPoint[q3].first * sPoint[q3].first + sPoint[q1].second * sPoint[q3].second * sPoint[q3].second - sPoint[q1].second * sPoint[q2].first * sPoint[q2].first - sPoint[q1].second * sPoint[q2].second * sPoint[q2].second - sPoint[q2].second * sPoint[q3].first * sPoint[q3].first - sPoint[q2].second * sPoint[q3].second * sPoint[q3].second) / (sPoint[q1].second * sPoint[q3].first - sPoint[q1].second * sPoint[q2].first - sPoint[q2].second * sPoint[q3].first - sPoint[q3].second * sPoint[q1].first + sPoint[q3].second * sPoint[q2].first + sPoint[q2].second * sPoint[q1].first)) / 2;
		res.first.second = ((-sPoint[q1].first * sPoint[q3].first * sPoint[q3].first - sPoint[q1].first * sPoint[q3].second * sPoint[q3].second + sPoint[q1].first * sPoint[q2].first * sPoint[q2].first + sPoint[q1].first * sPoint[q2].second * sPoint[q2].second + sPoint[q2].first * sPoint[q3].first * sPoint[q3].first + sPoint[q2].first * sPoint[q3].second * sPoint[q3].second - sPoint[q2].first * sPoint[q2].first * sPoint[q3].first - sPoint[q2].second * sPoint[q2].second * sPoint[q3].first + sPoint[q1].first * sPoint[q1].first * sPoint[q3].first - sPoint[q1].first * sPoint[q1].first * sPoint[q2].first + sPoint[q1].second * sPoint[q1].second * sPoint[q3].first - sPoint[q1].second * sPoint[q1].second * sPoint[q2].first) / (sPoint[q1].second * sPoint[q3].first - sPoint[q1].second * sPoint[q2].first - sPoint[q2].second * sPoint[q3].first - sPoint[q3].second * sPoint[q1].first + sPoint[q3].second * sPoint[q2].first + sPoint[q2].second * sPoint[q1].first)) / 2;
		res.second = dist(res.first, sPoint[q2]);

		return res;
	}

	else if(q2 != -1)
	{
		res.first = std::make_pair(
			(sPoint[q1].first + sPoint[q2].first) / 2,
			(sPoint[q1].second + sPoint[q2].second) / 2
		);

		res.second = dist(res.first, sPoint[q1]);
	}

	else if(q1 != -1)
	{
		res.first = std::make_pair(
			(sPoint[q1].first + sPoint[s].first) / 2,
			(sPoint[q1].second + sPoint[s].second) / 2
		);

		res.second = dist(res.first, sPoint[q1]);
		if(e == s + 1)
			return res;
	}

	else if(e == s + 1)
	{
		res.first = sPoint[s];
		res.second = 0;
		return res;
	}

	else
	{
		res.first = std::make_pair(
			(sPoint[s].first + sPoint[s + 1].first) / 2,
			(sPoint[s].second + sPoint[s + 1].second) / 2
			);

		res.second = dist(res.first, sPoint[s]);
	}

	for(unsigned int p = s; p < e; ++ p)
	{
		if(inCircle(res, sPoint[p]))
			continue;

		if(q2 != -1)
			res = minCircle(s, p, q1, q2, p);

		else if(q1 != -1)
			res = minCircle(s, p, q1, p);

		else
			res = minCircle(s, p, p);
	}

	return res;
}