0)
Test instructions
Test instructions is very simple, give a map of the island surrounded by the sea, the island with a vertex (the title data to ensure that the island is a convex polygon-the so-called convex polygons and concave polygonal difference, convex polygon is to the two sides of a polygonal arbitrarily extended into a straight line, if the other sides of the polygon are in this straight line side, Then this polygon is called convex polygon. Find the longest point on the island from the sea. That is, the shortest distance from the edge of an island on an island is the longest point in all points. That is, the center point of the inner circle in the island is asked. The shortest distance from this point to the edge of the island is output. That is, the radius of the inner circle in the island ...
Analysis:
The semi-planar intersection of the core point set is a point of the situation (with precision control), which is approximated by the dichotomy.
by x, y Range (0~10000), assuming a rectangular range large enough (if both long and wide are 0~10000, then the rectangular diagonal length =sqrt (10000*10000*2), the length <10000*2), So this large enough rectangle within the longest diameter should be less than 20000, we use rrr=200000 to do the upper limit, with lll=0 to do the lower limit, and then ask Mid= (LLL+RRR)/2, continuous two-point approximation, each approximation once to seek the point set of the polygon core, until rrr-lll< 1e-6, to achieve the accuracy required by the problem, that is to determine the scope of the point set can be regarded as a point, if the point set is not empty. We find this point, and the distance to be output is lll or RRR.
Attention:
① Semi-planar intersection + dichotomy, a lot of detail, error prone, even for the generation of templates, to understand every detail and careful enough. (For each step why, as far as possible, the understanding of the local notes in the code below, we will not repeat this.) )
② about double precision problem, use C++AC, G++wa on OJ.
Workaround:
//format output with printf control floating-point numbers: (If there is input, and use scanf words, all use%LF, namely scanf ("%lf", &f)) printf ("%.6lf\n", LLL); %LF only C + +, printf ("%.6f\n", LLL),//%f C + +, g++, local, are over//directly with the cout control floating point format output: (Fixed is the decimal point, Setprecision (n) is the total output Several valid numbers, both of which can be used to control the decimal point after the output of several valid numbers. Expansion, scientific is the exponential way of expression) Cout<<fixed<<setprecision (6) <<LLL<<endl; g++ Local C + + has gone//to include #include<iomanip>cout <<setiosflags (ios::fixed) <<setprecision (6) <<LLL <<endl;//the same as the previous sentence, another way of writing cout <<setiosflags (ios::fixed); Cout<<<setprecision (6) <<LLL< <endl;//as in the previous sentence, another way of writing//Description cout <<setiosflags (ios::fixed); similar to a switch, after opening, All cout after this will be similar to the effect of adding a fixed effect of the output because the local test and commit OJ The g++ result is the same, so that the codeblocks under Windows, and OJ (at least POJ) the g++ evaluation effect is similar//extended, Use cout to control the format output of floating-point numbers, expressed in exponential form: cout <<setiosflags (ios::scientific) <<amount <<endl; cout <<setiosflags (ios::fixed);//plus the second sentence is to turn the "switch" back, and then the output to re-use the decimal point to represent the
Reason: The earliest compilation standard, is a double, as long float, so in printf there will be%LF, with the hardware cost reduction, memory capacity becomes more and more large, with%f can output double precision data without worrying about memory explosion, so for C + + In the latest standard, both%f and%LF are accepted for printf output, but for g++, only printf is accepted with%f output and scanf is still read in%LF. (under Windows Codeblocks under the general GNU compilation, the effect with OJ on the g++ submission method) (g++, scanf can only%lf input, printf can only%f output has been tested; C + +, printf%f,%LF can also be tested, SCANF can be read in%lf,%f without test)
Reference: Fixed and setprecision for cout control the number of digits after the decimal point of a double data output,
1)
#include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include < math.h> #include <algorithm> #include <iomanip>//point point, Vecor vector Note Do not confuse using namespace std; Const double eps=1e-6;struct point{double x;double y; Point (Double a=0,double b=0): X (a), Y (b) {}};typedef, vector;struct line{point p;//a vector of that line on the line, Used to indicate the direction double ang;//the polar angle of the line, that is, the x positive half axis rotates to the angle of the line vector () {}//??? Line (Point P,vector v):p (P), V (v) {ang=atan2 (v.y,v.x);} Returns the polar BOOL operator < (const line&l) Const{return ang<l.ang;//Heavy Duty line <, by the angle from small to large sort, easy to use directly sort}};//about vector +- Overload of X: (vector inherits point, so the vector's overloading of these symbols also causes the point to get the same overloaded functionality as in the Polygonarea () function) vector operator + (vector a,vector b) { Return Vector (A.X+B.X,A.Y+B.Y);} Vector operator-(vector a,vector b) {return vector (A.X-B.X,A.Y-B.Y);} Vector operator * (vector a,double p) {return vector (a.x*p,a.y*p);} Part of the function about the vector: double Dot (vector a,vector b) {return a.x*b.x+a.y*b.y;} Inner product//dot product//Quantity Product Double Cross (Vector A,vectorb) {return a.x*b.y-a.y*b.x;} Outer product//cross product//vector product//fork Multiply double lenth (vector a) {return sqrt (Dot (a,a));} The unit normal vector of the modulus//vector a vector: vector Normal (vector a) {double l=lenth (a); return vector (-a.y/l,a.x/l);} Calculate the area of a convex polygon://Using the cross-/2== Triangle area of the adjacent vectors, the convex polygon is connected from one point to the other non-adjacent points to get a finite triangle double polygonarea (vector <Point> p) {int n= P.size ();d ouble area=0;for (int i=1;i<n-1;i++) {Area+=cross (p[i]-p[0],p[i+1]-p[0]);} return AREA/2;} Determine if the point P is on the left side of the vector L: (the direction of Vector P-L.P is from L.P to P) bool Onleft (line L,point p) {return cross (L.V,P-L.P) >0;} Point Getlineintersection (line A,line b) {Vector u=a.p-b.p;double t=cross (b.v,u)/cross (A.V,B.V); return a.p+a.v*t;} vector<point> halfplaneintersection (vector <Line> L) {//English, semi-planar int n=l.size (); Sort (L.begin (), L.end ()); /By the small to large order of the polar angle, line will < overloaded int first,last;vector<point> p (n);//defines the size of the vector? Stores the determined vertex of the current cut polygon vector<line> q (n);//stores the determined vector of the current cut polygon vector<point> ans;//stores the final set of kernel points q[first=last=0]=l [0];for (int i=1;i<n;i++) {///(why current vector l[i] cutting the current polygon forming a new polygon is only related to the last vector edge of the first determined vector Bien Hoa. Because they were previously sorted by a small to large angle.) while (first<last&&! Onleft (L[i],p[last-1])) {last--;} Judging the vector l[i] cuts the current polygon, and the position of the last determined vertex, if the last determined vertex is not on the left side of the vector, that is, the last determined vertex is on the outside of the vector, then the current vector enters, The last identified edge will be outside the newly formed polygon (because it is small to large by the angle, so there is not a part of the previous edge on the outside of the newly formed Polygon, the other part is in the case) while (first<last&&! Onleft (L[i],p[first])) {first++;} Judge the Vector L[i] cut the current polygon, and the position of the first determined vertex, if the first fixed point is not on the left side of the vector, also indicates that the first fixed point on the outside of the vector, then the current vector entered, the first determined edge will be on the outside of the newly formed Polygon q[++ last]=l[i];//last++ and ++last different if (fabs (Q[LAST].V,Q[LAST-1].V) <eps) {//If this adjacent two vector side direction is the same, Last--;if (Onleft (Q[LAST],L[I].P)) {q[last]=l[i];//Determine who is in the inside}}if (first<last) {p[last-1) (because the same vector edge is the same as the polar angle) ]=getlineintersection (Q[last-1],q[last]);//Get the latest point}}while (first<last&&!) for determining the polygon formed after the current cut. Onleft (Q[first],p[last-1])) last--;//determines the position relationship of the last determined point of the newly obtained polygon to the first edge, and if the point is on the outside side, also the final edge of the currently defined polygon if (last-first<=1) Return ans;//If it is an empty set, it returns to the null vectorp[last]=getlineintersection (Q[last],q[first]);//The last intersection is included in the defined point sets of the newly obtained polygon for (int i= first;i<=last;i++) {ans.push_back (p[i]);//Place the identified vertices in a new vector and return to}return ans;} int main () {inT Num;while (~scanf ("%d", &num) &&num) {vector <Point> p,v,normal;int x,y;for (int i=0;i<num;i++) { scanf ("%d%d", &x,&y);p. Push_back (Point (x, Y));} If the polygon area obtained by the fork is <0, the point is entered clockwise, and the array is reversed with the library function reverse: if (Polygonarea (p) <0) reverse (P.begin (), P.end ()); for (int i= 0;i<num;i++) {v.push_back (p[(i+1)%num]-p[i]); Normal.push_back (Normal (V[i)));//obtain and store the normal vector}double lll=0 for each vector; Double rrr=20000;//Why is the RRR 20000? X, y are from 0 to 10000, so the diagonal of the four-point rectangle is sqrt (2*10000*10000) <20000, is this understood? while (rrr-lll>0.000001) {//1e-6 is 0.000001, when Rrr-lll<1e-6, the set of kernel points to be evaluated, can be considered a point//every time the while loop is a two-point advance vector< Line>l;double mid=lll+ (rrr-lll)/2;//for traverse all sides forward for (int. i=0;i<num;i++) {L.push_back (line (p[i]+normal[i]*mid , V[i]);//The vector edges that are stored by each vector side to propel the mid distance, that is, the new Polygon}vector<point>poly=halfplaneintersection (L) that is obtained after the propulsion;// By Nlogn the time complexity of the straight line cut, this time the two points are pushed after the new polygon's kernel point set if (Poly.empty ()) {//cout<< "1:" <<mid<<endl; Rrr=mid; }//if the kernel point set is empty, this one pushes the mid distance too large, redefining the upper limit with the new mid-propulsion distance, and re-propulsion the else{//cout<< "2:" <<mid<<endl; lll=mid;//point set is not empty, the lower bound is redefined, waiting for the next while conditional statement to determine whether the next second sub-propulsion}}cout <<setiosflags (ios::fixed) << Setprecision (7) <<lll<<endl;//printf ("%.6lf\n", LLL);//output 6 digits to meet the problem, LF is a double output format, Also output lll or the RRR is OK. }}
2) Special Judge refers to the answer is not unique, this problem is because the accuracy is not less than XXX, so the answer is not the only use of special Judge.
Most distant point from the Sea
Time Limit: 5000MS |
|
Memory Limit: 65536K |
Total Submissions: 4676 |
|
Accepted: 2156 |
|
Special Judge |
Description
The main land of Japan called Honshu is a island surrounded by the sea. In such-an, it's natural to ask a question: "Where's the most distant point from the sea?" The answer to this question for Honshu is found in 1996. The most distant point was located in former Usuda, Nagano Prefecture, whose distance from the sea was 114.86 km.
In this problem, you is asked to write a program which, given a map of a, finds the most distant point from the s EA in the island, and reports its distance from the sea. In order to simplify the problem, we have consider maps representable by convex polygons.
Input
The input consists of multiple datasets. Each dataset represents a map of the island, which is a convex polygon. The format of a dataset is as follows.
Every input item in a dataset is a non-negative integer. The input items in a line is separated by a space.
N in the first line is the number of vertices of the polygon, satisfying 3≤ n ≤100. Subsequent n lines is the x-and y-coordinates of the n vertices. Line segments (Xi, Yi) – (Xi+1, yi+ 1) (1≤ i ≤ n ? 1) and The line segment (xn, yn) – (x1, y1) Form the border of the polygon in Counterc Lockwise order. That's, these line segments see the inside of the polygon in the left of their directions. All coordinate values is between 0 and 10000, inclusive.
You can assume the polygon are simple, that's, its border never crosses or touches itself. As stated above, the given polygon is always a convex one.
The last dataset was followed by a line containing a single zero.
Output
For each dataset in the input, one line containing the distance of the most distant point from the sea should be output. An output line should not contain extra characters such as spaces. The answer should not has an error greater than 0.00001 (10?5). You could output any number of digits after the decimal point, provided that the above accuracy condition is satisfied.
Sample Input
40 010000 010000 100000 1000030 010000 07000 100060 40100 20250 40250 70100 900 7030 010000 100005000 50010
Sample Output
5000.000000494.23364134.5429480.353553
Source
Japan 2007
Because the local test is the same as the g++ result of the commit OJ, it is considered to be similar to POJ evaluation on OJ (at least g++) under Windows Codeblocks
Example 4.10 poj3525/la3890 The farthest point of the sea from the semi-planar intersection + dichotomy + the number of significant digits after the decimal point processing method/printf and g++, C + + problems