poj 2284(欧拉公式的推广:线段分平面成几个区域:n+m-r==2)
2012-08-10 20:50
309 查看
欧拉公式:如果G是一个阶为n,边数为m 且含有R个区域的联通平面图,则恒有等式:n-m+R==2;
推广:具有k 个联通分支的平面图G,有: n-m+R==k+1其中n,m,r,分别为阶数,边数,和区域数。
回到题目:给出一些点 ,首尾相连,求分成的区域数
推广:具有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; }
相关文章推荐
- POJ 2284-That Nice Euler Circuit(计算几何_欧拉定理求平面被分成的区域数)
- POJ--2284--That Nice Euler Circuit【平面图欧拉公式】
- 用N个三角形最多可以把平面分成几个区域?
- POJ 3449 Geometric Shapes(判断几个不同图形的相交,线段相交判断)
- POJ 3449 Geometric Shapes(判断几个不同图形的相交,线段相交判断)
- zoj 3574 求给定区间内n条线段能将区间内的区域划分成几个区域
- hdu 1249 N个三角形把平面分成几个区域
- That Nice Euler Circuit - POJ 2284 欧拉公式
- 一些项目——用N个三角形最多可以把平面分成几个区域?
- HDU-用N个三角形最多可以把平面分成几个区域
- n个三角形能把平面分成几个区域 2011-3-2 22:20
- 用N个三角形最多可以把平面分成几个区域
- POJ 3449 Geometric Shapes(判断几个不同图形的相交,线段相交判断)
- 平面上欧拉定理:poj 2284( LA 3263 ) That Nice Euler Circuit
- HDU 1249 三角形 三角形最多可以把平面分成几个区域? 递推找规律题
- POJ 2653 Pick-up sticks (线段相交)
- POJ 1410 Intersection(一线段是否与矩阵相交)
- poj 1106(半圆围绕圆心旋转能够覆盖平面内最多的点)
- 程序中几个内存区域的名称
- poj 1523 求割点把一个图分成几个联通部分