Problem surface
Given N points, let's draw the smallest circle that contains all the points.
Analysis
This problem is actually to find out a circle determined by three points, which can contain all other points.
There is a close relationship with three points in a circle. First, three points in a circle.
There are two cases of three points in a circle: three points are collinear or non collinear, two farthest points are collinear to form diameter, and non collinear to form a triangle circumscribed circle
Considering the circumscribed circle situation, it is easy to find the center of circle by using sine theorem, in fact, the difficulty is to find the center of circle, that is, to express the coordinates of the outer center by using the coordinates of three vertices of triangle.
The three points in the code here refer to the calculation of the center of a circle This article.
In fact, there are other methods, such as the intersection of the center of two lines, the intersection of the center of a vector perpendicular to the center of a circle, etc., but it is relatively easy to use the three-point coordinate of a triangle to directly implement the code
Let's talk about the minimum circle covering. In fact, we use the mathematical induction method. If we have covered the first i points, we will try to create a circle to cover i+1 points.
Consider the following steps:
1. It is known that 1 ~ i-1 points have been covered by circle Ci − 1c {i-1} Ci − 1. Now, i want to add the ith point and let it also be covered by circle
2. If the ith point is already in the circle Ci − 1c {I-1} Ci − 1, then the next circle Ci=Ci − 1c_i = C {I-1} Ci=Ci − 1, and go back to the first step to continue
3. If not, a new circle needs to be constructed with 1 ~ i points. First, the newly added point i needs to be on the edge of the circle (critical case), which also determines a point on the circle
4. Round t1t {1} T1 with the first point and the ith point. If there is a point J (J < i) that is not in t1t {1} T1, it is taken as the second point on the edge of CIC {ICI.
5. Circle T2T ﹤ 2t2 with two points i and j. in the same four steps, find the point K (k < j < i) that is not in the circle T2T ﹤ 2t2. If it exists, then K is the third point on the edge of circle CIC ﹤ ICI.
6. Now the three points of i j k are all on the circle CIC ﹣ ICI, and it can be proved that CIC ﹣ ICI contains all points from 1 to I, so we use three points to construct CIC ﹣ ICI, and go back to 1 to continue the iteration.
Iteration to CNCN ends
This seems to be a three-layer loop, but in fact, it expects complexity O(n), but in order to prevent data from being inappropriate, we need to scramble the given n points before processing, which can be realized by random_shuffle()
Code
#include <iostream> #include<algorithm> #include<string.h> #include<string> #include<math.h> #include<iomanip> using namespace std; struct Point { double x, y; Point() {} Point(double x,double y):x(x),y(y){} };//Save point structure inline double dis(Point &p1, Point &p2)//Distance between two points { return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); } inline double sqr(double x) { return x * x; }//square class min_circle { private: Point p[100005]; int n; public: Point center;//Represents the center of the circle constructed every time double r;//Represents the radius of each construction void init(int n) { this->n = n; for (int i = 0; i < n; i++)cin >> p[i].x >> p[i].y; random_shuffle(p, p + n);//Disruption, avoid card } void circular()//Construction circle sequence { r = 0, center = p[0]; for (int i = 1; i < n; i++)//Try to determine if the ith point is not in the circle. If it is, enter the next point. If it is not, create a circle with p[i] on the edge if (dis(center, p[i]) - r > 1e-8)//p[i] outside the circle made before { r=dis(p[0],p[i])/2;//Take p[0] and p[i] as diameter to make a circle, find out the point p[j] outside the circle, as the second point on the edge of this circle center.x = (p[0].x + p[i].x) / 2; center.y= (p[0].y + p[i].y) / 2; for (int j = 0; j < i; j++) { if (dis(center, p[j]) - r > 1e-8)//We found this kind of j outside the circle { r = dis(p[i], p[j]) / 2;//p[i] and p[j] are the final points on the edge of the circle constructed in this round. Take these two as the diameter to construct a circle, and try to find the k point outside center.x = (p[i].x + p[j].x) / 2; center.y = (p[i].y + p[j].y) / 2; for (int k = 0; k < j; k++) { if (dis(center, p[k]) - r > 1e-8)//Find this kind of k { center = build_circle(p[i], p[j], p[k]);//It is found that p[i],p[j],p[k] are all on the edge of the circle constructed in this round, and the circle is determined r = dis(center, p[i]); } } } } } } Point build_circle(Point a, Point b, Point c) {//Three point making double a1, a2, b1, b2, c1, c2; Point ans; a1 = 2 * (b.x - a.x), b1 = 2 * (b.y - a.y), c1 = sqr(b.x) - sqr(a.x) + sqr(b.y) - sqr(a.y); a2 = 2 * (c.x - a.x), b2 = 2 * (c.y - a.y), c2 = sqr(c.x) - sqr(a.x) + sqr(c.y) - sqr(a.y); if (fabs(a1-0.0)<1e-8) { ans.y = c1 / b1; ans.x = (c2 - ans.y * b2) / a2; } else if (fabs(b1-0)<1e-8) {//Because there are two kinds of denominators, the two cases are specially judged ans.x = c1 / a1; ans.y = (c2 - ans.x * a2) / b2; } else { ans.x = (c2 * b1 - c1 * b2) / (a2 * b1 - a1 * b2); ans.y = (c2 * a1 - c1 * a2) / (b2 * a1 - b1 * a2); } return ans; } }MC; int main() { ios::sync_with_stdio(false); int n; cin >> n; MC.init(n);//Reading and randomization, disruption MC.circular(); cout << fixed << setprecision(10) << MC.r << endl << MC.center.x << " " << MC.center.y; return 0; }