欧拉公式:如果G是一个阶为n,边数为m 且含有R个区域的联通平面图,则恒有等式:n-m+R==2;
推广:具有k 个联通分支的平面图G,有: n-m+R==k+1其中n,m,r,分别为阶数,边数,和区域数。
回到题目:给出一些点 ,首尾相连,求分成的区域数
#include<cstdio> #include<cstring> #include<stdlib.h> #define inf 0xffffff #include<iostream> #include<cmath> #define NUM 22 #include <algorithm> using namespace std; const double eps=1e-6; struct point { double x,y; point(double a=0,double b=0) {x=a;y=b;} }; bool operator< (point a, point b) { return a.x<b.x||a.x==b.x&&a.y<b.y; } bool operator == (point a,point b) { return abs(a.x-b.x)<eps&&abs(a.y-b.y)<eps; } struct Lineseg { point s,e; Lineseg(point a, point b){s=a;e=b;} }; struct Line { double a,b,c; }; bool online(Lineseg L,point p)//判断p是否在线段L上 { return abs((L.e.x-L.s.x)*(p.y-L.s.y)-(p.x-L.s.x)*(L.e.y-L.s.y))<eps&&(p.x-L.s.x)*(p.x-L.e.x)<eps&&(p.y-L.s.y)*(p.y-L.e.y)<eps; } Line Makeline(Lineseg tmp)//线段L变成L { Line L; int x1=tmp.s.x; int y1=tmp.s.y; int x2=tmp.e.x; int y2=tmp.e.y; if(y2-y1>0) { L.a=(y2-y1); L.b=(x1-x2); L.c=(x2*y1-x1*y2); } else { L.a=(y1-y2); L.b=(x2-x1); L.c=(x1*y2-x2*y1); } return L; } bool Lineinter(Line x,Line y,point &q)//直线X,Y相交于点q { double d=x.a*y.b-y.a*x.b; if(abs(d)<eps) return false; q.x=(y.c*x.b-x.c*y.b)/d; q.y=(y.a*x.c-x.a*y.c)/d; return 1; } bool Lineseginter(Lineseg aa,Lineseg bb,point &q)//线段aa,bb如果相交则返回交点q { Line a,b; a=Makeline(aa); b=Makeline(bb); if(Lineinter(a,b,q)) return online(aa,q)&&online(bb,q); else return false; } bool cmp(point a ,point b) { if(a.x==b.x) return a.y<b.y; else return a.x<b.x; } point p[96003]; point inter[98000]; int N; int main() { int m,n; int T=0; while(scanf("%d",&N),N) { m=n=0; int cnt=0; for(int i=0;i<N;i++) scanf("%lf %lf",&p[i].x,&p[i].y); for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { Lineseg L1(p[i],p[(i+1)%N]),L2(p[j],p[(j+1)%N]); point q; if(Lineseginter(L1,L2,q)) inter[cnt++]=q; } } sort(inter,inter+cnt,cmp); n=unique(inter,inter+cnt)-inter;//去重复的点 for(int i=0;i<n;i++) { for(int j=0;j<N;j++) { Lineseg t(p[j],p[(j+1)%N]); if(online(t,inter[i])&&!(t.s==inter[i]))m++; } } T++; printf("Case %d: There are %d pieces.\n",T,m+2-n);//欧拉定理 } return 0; }