3263-that Nice Euler circuit Time limit:3.000 seconds |
Description Little Joey invented a Scrabble machine this he called Euler, after the great mathematician. In He primary school Joey heard about the nice stories of how to Euler started the study about graphs. The problem in that stories was-let me remind you-to draw a graph on a paper without lifting your pen, and finally retur N to the original position. Euler proved that could does this if and only if the (planar) graph you created have the following the properties: (1) Th e graph is connected; and (2) every vertex in the graph has even degree.
Joey's Euler machine works exactly. The device consists of a pencil touching the paper, and a control center issuing a sequence of instructions. The paper can be viewed as the infinite two-dimensional plane; That's means you don't need to worry about if the pencil would ever go off the boundary.
In the beginning, the Euler machine would issue an instruction of the form (X0, Y0) which moves the pencil to some starting Position (X0, Y0). Each subsequent instruction are also of the form (X ', Y '), which means to move the pencil from the previous position to the New position (X ', Y '), thus draw a line segment on the paper. You can be sure, the new position is different from the previous position for each instruction. At last, the Euler machine would always issue a instruction that move the pencil back to the starting position (X0, Y0). In addition, the Euler machine would definitely not draw any lines this overlay other lines already drawn. However, the lines may intersect.
After all the instructions is issued, there'll be a nice picture on Joey's paper. You see, since the pencil was never lifted from the paper and the picture can be viewed as an Euler circuit.
Your job is to count how many pieces (connected areas) was created on the paper by those lines drawn by Euler.
Input there is no more than test cases. Ease case starts with a line containing an integer N >= 4, which was the number of the instructions in the test case. The following N pairs of integers give the instructions and appear on a single line separated by single spaces. The first pair is the first instruction that gives the coordinates of the starting position. You may assume there is no more than instructions in each test case, and all the integer coordinates is in the range (-300, 300). The input is terminated if N is 0.
Output for each test case there'll be one output line in the format
Case X:there is w pieces.,
where x is the serial number starting from 1.
Note:the figures below illustrate the and the sample input cases.
Sample Input
5
0 0 0 1 1 1 1 0 0 0
7
1 1 1 5 2 1 2 5 5 1 3 5 1 1
0
Sample Output
Case 1:there is 2 pieces.
Case 2:there is 5 pieces.
Source Shanghai 2004
Main Topic
n points are given on the plane to find out the number of plane regions
Thinking of solving problems
Euler's theorem: the number of vertices, the number of sides and the number of polygons are v,e,f respectively, then there are v+f-e=2
Vertex number v:n vertex + intersection, note that there is a three-wire common point, find all the intersection to go to weight, using the de-heavy function unique to re-function unique
The number of edges e:n, if there is more intersection of the number of points, note that there are three-wire common point of the situation, is not a simple intersection of more to the edge, but usually through the intersection of the number of edges Plus +, all to traverse the edge to determine whether the intersection is on the edge, meet on the e++
Refer to the introduction to algorithmic competition-the fourth chapter of the training guide-Calculating geometry
Reference code + partial comment
#include <iostream> #include <cstdio> #include <algorithm> #include <map> #include <vector > #include <queue> #include <cstring> #include <cmath> #include <climits> #define EPS 1e-10 usi
NG namespace Std;
typedef long Long LL;
const int Inf=int_max;
const int MAXN = 300+10;
int dcmp (double x) {///three-state function, overcoming floating-point precision traps, judging x==0?x<0?x>0?
if (fabs (x) <eps) return 0;else return x<0?-1:1;
} struct point{double x, y;
Point (Double x=0,double y=0): X (x), Y (y) {}//constructor, convenient for code writing};
typedef point Vector;//vector is the alias of point 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);} Vector operator/(vector a,double p) {return vector (a.x/p,a.y/p);} bool operator < (const point& A,const point& b) {return a.x<b.x| |
(A.X==B.X&&A.Y<B.Y);} BOOL operator = = (Const point& a,consT point& b) {return dcmp (a.x-b.x) ==0&&dcmp (A.Y-B.Y) ==0;} Double Dot (vector a,vector B) {return a.x*b.x+a.y*b.y;} double Length (vector A) {return sqrt (Dot (a,a));} Double Angle (
Vector A,vector b) {return ACOs (Dot (A, A)/length (A)/length (B)), Double Cross (Vector a,vector B) {return a.x*b.y-a.y*b.x;} Vector rotation, RAD is radian is not angular vector Rotate (vector a,double rad) {return vector (A.x*cos (RAD)-a.y*sin (RAD), A.x*sin (RAD) +a.y*cos (
rad));} Line intersection, make sure the two lines p+tv,q+tw have a unique intersection before calling.
When and only if Cross (v,w) is not 0 point getlineintersection (Point p,vector v,point q,vector w) {Vector u=p-q;
Double T=cross (w,u)/cross (V,W);
return p+v*t; }//Segment specification intersection decision BOOL Segmentproperintersection (point a1,point a2,point b1,point b2) {double C1=cross (A2-A1,B1-A1), C2=cross
(A2-A1,B2-A1), C3=cross (B2-B1,A1-B1), C4=cross (B2-B1,A2-B1);
Return dcmp (C1) *dcmp (C2) <0 && dcmp (C3) *dcmp (C4) <0; }//Point on-line (three-point collinear) to determine bool Onsegment (points p,point a1,point A2) {return dcmp (Cross (a1-p,a2-p)) ==0&&dcmp (Dot (A1-p,
A2-P)) <0; } pointP[maxn],v[maxn*maxn];//p[] Stores n points, v[] stores possible vertices int main () {///Freopen ("Input.txt", "R", stdin);
int n,kase=0; while (scanf ("%d", &n) ==1&&n) {for (int i=0;i<n;i++) {scanf ("%lf%lf", &p[i].x,&p[i].y);
V[i]=p[i];} n--;
n vertices, in which there is a repetition, to subtract//to find the number of vertices V, initially N, considering that there may be a three-wire common point of the case, to find all the intersection again to re-v=n int;
for (int i=0;i<n;i++) for (int j=i+1;j<n;j++) if (Segmentproperintersection (p[i],p[i+1],p[j],p[j+1]))
V[v++]=getlineintersection (P[i],p[i+1]-p[i],p[j],p[j+1]-p[j]);
Sort (v,v+v);
V=unique (V,V+V)-v;//process, first sort, finally get the vertex number V//And then the Edge e, initialize the e=n, pay attention to three-wire common point of the situation, not a few intersection edge + a few int e=n;
for (int i=0;i<v;i++) for (int j=0;j<n;j++) if (Onsegment (v[i],p[j],p[j+1])) e++;//traverse Edge, point and line indicate intersection, e++
printf ("Case%d:there is%d pieces.\n", ++kase,e+2-v);
} return 0;
}