In fact, the solution is not complicated, that is, first finding the convex hull of all vertices, and then finding the straight line connecting each adjacent point in these convex points, at the same time, locate the endpoint of the straight line in the polygon, such as the line 1, 2, 5, 6 in Object1. The endpoint is. If the center of gravity is connected to the two points and the straight line is acute, the straight line is stable and the so-called minimum point required by the question can be found. My code can be tested by myself, but it is not a problem. The Graham's Scan method is used to find the convex hull.
[Cpp]
# Include <iostream>
# Include <stack>
# Include <vector>
# Include <math. h>
# Include <iomanip>
Using namespace std;
Typedef struct point
{
Double x;
Double y;
Int index; // the index of the Record Point
} Point;
Int cal_max (int index, vector <int> * myv, vector <point> * vertices, point mass );
Int find_stable (stack <int> * mys, vector <point> * vertices, point mass );
Void find_first (vector <point> * vertices );
Void sort (vector <point> * vertices );
Bool is_left (int index, stack <int> * mys, vector <point> * vertices );
Void find_convex_hull (vector <point> * vertices, stack <int> * mys );
Int main ()
{
Char name [20];
Vector <point> vertices;
Stack <int> mys;
Point mass;
While (cin> name)
{
Vertices. clear ();
While (mys. size ()> 0)
Mys. pop ();
If (strcmp (name, "#") = 0)
{
Return 0;
}
Cin> mass. x> mass. y;
Point tmp; int index = 0;
While (cin> tmp. x> tmp. y)
{
If (tmp. x = 0 & tmp. y = 0)
{
Break;
}
Tmp. index = ++ index;
Vertices. push_back (tmp );
}
Find_convex_hull (& vertices, & mys); // find a convex hull
Int min = find_stable (& mys, & vertices, mass );
Cout <setw (20) <setiosflags (ios: left) <name <setw (1) <min <endl;
// Cout <name <<'' <min <endl;
}
}
// Graham's Scan Method for Finding convex packets
// Vertices: Point Set, mys: convex packet stack
Void find_convex_hull (vector <point> * vertices, stack <int> * mys)
{
Find_first (vertices); // locate the vertex with the smallest y coordinate and put it in the first place.
Sort (vertices); // sort by and y0 angle coordinates
Mys-> push (0); mys-> push (1); mys-> push (2 );
For (int I = 3; I <vertices-> size (); I ++)
{
Int pos = mys-> top ();
While (! Is_left (I, mys, vertices ))
{
Mys-> pop ();
}
Mys-> push (I );
}
}
// Calculate the maximum baseline of a straight line consisting of index and index + 1 in myv
// Myv: Point Set in the convex hull; vertices: Point Set; mass: center of gravity Coordinate
// Returns the largest baseline.
Int cal_max (int index, vector <int> * myv, vector <point> * vertices, point mass)
{
Int start = index, end = index + 1;
If (end = myv-> size ())
End = 0;
Start = myv-> at (start); end = myv-> at (end );
Point left, right;
Int max_index = 0, min_x = 65535, max_x =-65535;
For (int I = 0; I <myv-> size (); I ++)
{
Int ano = myv-> at (I );
Double rate1 = (vertices-> at (end ). y-vertices-> at (start ). y)/(vertices-> at (end ). x-vertices-> at (start ). x );
Double rate2 = (vertices-> at (ano ). y-vertices-> at (start ). y)/(vertices-> at (ano ). x-vertices-> at (start ). x );
If (vertices-> at (ano). x = vertices-> at (start). x)
Rate2 = (vertices-> at (ano ). y-vertices-> at (end ). y)/(vertices-> at (ano ). x-vertices-> at (end ). x );
If (vertices-> at (ano ). x = vertices-> at (start ). x & vertices-> at (end ). x = vertices-> at (start ). x)
Rate2 = rate1 = 1;
If (rate1 = rate2)
{
If (vertices-> at (ano). index> max_index)
Max_index = vertices-> at (ano). index;
If (vertices-> at (ano). x> max_x)
{
Max_x = vertices-> at (ano). x;
Right = vertices-> at (ano );
}
If (vertices-> at (ano). x <min_x)
{
Min_x = vertices-> at (ano). x;
Left = vertices-> at (ano );
}
}
}
// Determine whether the center of gravity is within the range
Point vec1, vec2;
Vec1.x = mass. x-left. x; vec1.y = mass. y-left. y;
Vec2.x = right. x-left. x; vec2.y = right. y-left. y;
If (vec1.x * vec2.x + vec1.y * vec2.y) <0)
Return-1;
Vec1.x = mass. x-right. x; vec1.y = mass. y-right. y;
Vec2.x = left. x-right. x; vec2.y = left. y-right. y;
If (vec1.x * vec2.x + vec1.y * vec2.y) <0)
Return-1;
Return max_index;
}
// Find the stable minimum baseline
// Mys: Point Set in the convex hull; vertices: Point Set; mass: center of gravity Coordinate
// Returns the smallest baseline.
Int find_stable (stack <int> * mys, vector <point> * vertices, point mass)
{
Vector <int> myv;
While (mys-> size ()> 0)
{
Myv. push_back (mys-> top ());
Mys-> pop ();
}
Int min_index = 65535;
For (int I = 0; I <myv. size (); I ++)
{
// Determine the straight line Formula
Int this_min = cal_max (I, & myv, vertices, mass );
If (this_min> = 0 & this_min <min_index)
{
Min_index = this_min;
}
}
If (min_index = 65536)
Return 0;
Return min_index;
}
// Determine whether the vector direction is left
// Index: Position of the vertex to be determined; mys: Point Set in the convex hull; vertices: Point Set
// True: Yes; false: No, right-Facing
Bool is_left (int index, stack <int> * mys, vector <point> * vertices)
{
Int first = mys-> top (); mys-> pop ();
Int second = mys-> top (); mys-> push (first );
Point vec1, vec2;
Point vec0; vec0.x = 0;
Vec1.y = vertices-> at (first). y-vertices-> at (second). y;
Vec1.x = vertices-> at (first). x-vertices-> at (second). x;
Vec2.y = vertices-> at (index). y;
Vec2.x = vertices-> at (index). x;
Vec0.y = vertices-> at (first). y-vertices-> at (first). x * vec1.y/vec1.x;
If (vec1.x> 0)
{
If (vec2.y> = vec2.x * vec1.y/vec1.x + vec0.y)
Return true;
}
Else if (vec1.x <0)
{
If (vec2.y <= vec2.x * vec1.y/vec1.x + vec0.y)
Return true;
}
Else
{
If (vec1.y * (vec2.x-vertices-> at (first). x) <= 0)
Return true;
}
Return false;
}
// Locate the minimum y coordinate point and place it at 0.
// Vertices: Point Set
Void find_first (vector <point> * vertices)
{
For (int I = 0; I <vertices-> size (); I ++)
{
If (vertices-> at (I). y <vertices-> at (0). y)
Swap (vertices-> at (I), vertices-> at (0 ));
}
}
// Sort all vertices except the first vertex based on the level angle of the zero vertex (lazy insertion sorting ...)
// Vertices: Point Set
Void sort (vector <point> * vertices)
{
For (int I = 1; I <vertices-> size (); I ++)
{
For (int j = I; j> 1; j --)
{
// Use the vector cosine theorem for tomorrow
Point vec0, vec1, vec2;
Vec0.x = 1; vec0.y = 0;
Vec1.y = vertices-> at (j). y-vertices-> at (0). y;
Vec1.x = vertices-> at (j). x-vertices-> at (0). x;
Vec2.y = vertices-> at (J-1). y-vertices-> at (0). y;
Vec2.x = vertices-> at (J-1). x-vertices-> at (0). x;
Double cos1 = (vec1.x * vec0.x + vec1.y * vec0.y)/sqrt (vec1.x * vec1.x + vec1.y * vec1.y) * (vec0.x * vec0.x + vec0.y * vec0.y ));
Double cos2 = (vec2.x * vec0.x + vec2.y * vec0.y)/sqrt (vec2.x * vec2.x + vec2.y * vec2.y) * (vec0.x * vec0.x + vec0.y * vec0.y ));
If (cos1> cos2)
{
Swap (vertices-> at (j), vertices-> at (J-1 ));
}
/* Double rate1 = (vertices-> at (j ). y-vertices-> at (0 ). y)/(vertices-> at (j ). x-vertices-> at (0 ). x );
Double rate2 = (vertices-> at (J-1 ). y-vertices-> at (0 ). y)/(vertices-> at (J-1 ). x-vertices-> at (0 ). x );
If (vertices-> at (j). x-vertices-> at (0). x = 0)
Rate1 = 65535;
If (vertices-> at (J-1). x-vertices-> at (0). x = 0)
Rate2 = 65535;
If (rate1 * rate2> 0 & rate1 <rate2)
{
Swap (vertices-> at (j), vertices-> at (J-1 ));
}
Else if (rate1 * rate2 <0 & rate1 <0)
{
Swap (vertices-> at (j), vertices-> at (J-1 ));
}
Else if (rate1 * rate2 = 0 & (vertices-> at (j ). x> vertices-> at (0 ). x | vertices-> at (J-1 ). x <vertices-> at (0 ). x ))
{
Swap (vertices-> at (j), vertices-> at (J-1 ));
}*/
}
}
}