UVa1342That Nice Euler Circuit(欧拉函数)

来源:互联网 发布:企业网络商学院 编辑:程序博客网 时间:2024/06/05 16:08

UVa1342 That Nice Euler Circuit(欧拉函数)

题意:给定n个点连成的多边形,求把平面分成了多少块。
这个题用到欧拉定理:应该算是多面体欧拉定理,简单多面体定点数V,棱数E面数F
满足公式:V+F-E=2
二维平面也满足这个公式,涉及到二维拓扑多面体。
有了公式求解面数就好求面数,不知道公式还不知道怎么做。
本题思路:求解顶点数和棱数,定点数有开始所有顶点加上,枚举任意两条边求交点,然后加入到V数组
而后排序重,棱数为开始棱数加上,已求到的所有顶点是否在任意边上,若在,则把这条边分成两个,棱数加1。

AC代码:

#include<bits/stdc++.h>using namespace std;struct Point{    double x,y;    Point(double x=0,double y=0):x(x),y(y) {}};typedef Point Vector;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);}const double eps=1e-10;int dcmp(double x){    if(fabs(x)<eps) return 0; else return x < 0 ? -1 : 1;}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,B) / Length(A) / Length(B) ); }double Cross(Vector A,Vector B) { return A.x*B.y-A.y*B.x; }/**first input right Edge,Cross product be Positive.*/double Area2(Point A,Point B,Point C) { return Cross(B-A,C-A); }Vector Rotate(Vector A,double rad){    return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));}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;}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;}bool OnSegment(Point p,Point a1,Point a2){    return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;}const int maxn = 300 + 50;Point V[maxn*maxn],P[maxn];int e,v;/**Euler TheoremV+F-E=2;*/int main(){    int n,c=1;    while(scanf("%d",&n)&&n){        for(int i=0;i<n;i++){            scanf("%lf%lf",&P[i].x,&P[i].y);            V[i]=P[i];        }        n-=1;        e=n,v=n;        /**        find if there be more Points of intersection        */        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+1);        v = unique(V,V+v+1)-V;        /**        find if there be more Edges        */        for(int i=0;i<v;i++)            for(int j=0;j<n;j++)            if(OnSegment(V[i],P[j],P[j+1])) e++;        printf("Case %d: There are %d pieces.\n",c++,e-v+2);    }    return 0;}

血洗几何

0 0