UVALive 3263 That Nice Euler Circuit 计算几何+欧拉定理

    这是白书上面的原题,题意是求闭合的n条线段把平面分成了几个区域。 

就是一个 欧拉定理 V+F-E=2   。 v是图的顶点数,F是图的面数,E是图的边数。

·我自己在写的时候有一个地方跟费解的,我把每个节点都重复了算了一次,最后去重,结果是wa了。到现在还不清楚问什么。。。。。 反正都去了重的,重复一遍为什么错了。T_T。


</pre><pre name="code" class="html">#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#include<stdlib.h>
using namespace std;
const int mod=99999997;
const int mmax=200010;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3fffffff;

/*

double Dot(Vector A,Vector B)  点积
double Length(Vector A)  取模
double Angle(Vector A,Vector B) 夹角
double Cross(Vector A,Vector B) 叉积
double Area2(Point A,Point B,Point C) 有向面积
Vector Ratate(Vector A,double rad)  向量旋转
Vector Normal(Vector A) 法向量
Point GetLineIntersection(Point P,Point Q,Vector v,Vector w) 直线相交  line1 P+tv  line2 Q+tw
double Dis_Point_Line(Point P,Point A,Point B) 点到直线距离
Point GetLineProjection(Point P,Point A,Point B) 点在直线上投影
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2) 线段规范相交
bool OnSegment(Point p,Point a1,Point a2)  点在直线上
double PolygonArea(Point *p,int n) 多边形面积

*/
struct Point
{
    double x,y;
    Point (double x=0.0,double y=0.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 - (Point A,Point 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);
}

int sgn(double x)// 符号函数
{
    if(fabs(x)<eps)
        return 0;
    return x<0?-1:1;
}


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 sgn(a.x-b.x)==0&&sgn(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;
}
double Area2(Point A,Point B,Point C)
{
    return Cross(B-A,C-A);
}
//向量旋转
Vector Ratate(Vector A,double rad)
{
    return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A) //单位法线
{
    double L=Length(A);
    return Vector(-A.y/L,A.x/L);
}

//直线相交  line1 P+tv  line2 Q+tw
Point GetLineIntersection(Point P,Point Q,Vector v,Vector w)
{
    Vector u=P-Q;
    double t=Cross(w,u) / Cross(v,w);
    return P+v*t;
}
//点到直线距离
double Dis_Point_Line(Point P,Point A,Point B)
{
    Vector v1=B-A,v2=P-A;
    return fabs(Cross(v1,v2)/Length(v1));
}
//点在直线上的投影
Point GetLineProjection(Point P,Point A,Point B)
{
    Vector v=B-A;
    return A+v*(Dot(v,P-A) / Dot(v,v) );
}
//线段规范相交
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
{
    double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1);
    double c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
    return sgn(c1)*sgn(c2)<0&&sgn(c3)*sgn(c4)<0;
}

//点是否在线段上
bool OnSegment(Point p,Point a1,Point a2)
{
    return sgn(Cross(a1-p,a2-p))==0 && sgn(Dot(a1-p,a2-p))<0;
}

//多边形又向面积
double PolygonArea(Point *p,int n)
{
    double area=0.0;
    for(int i=1;i<n-1;i++)
        area+=Cross(p[i]-p[0],p[i+1]-p[0]);
    return area/2;
}



Point p[310];
Point V[91000];
int main()
{
    int n,e,ca=0,cnt;
    while(cin>>n&&n)
    {

        cnt=0;
        for(int i=0;i<n;i++)
        {
            scanf("%lf %lf",&p[i].x,&p[i].y);
            V[cnt++]=p[i];
        }
        for(int i=1;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                if(SegmentProperIntersection(p[i],p[i-1],p[j],p[j-1]))
                {
                    V[cnt++]=GetLineIntersection(p[i],p[j],p[i]-p[i-1],p[j]-p[j-1]);
                }
            }
        }
        sort(V,V+cnt);
        cnt=unique(V,V+cnt)-V;
        e=n-1;
        for(int i=0;i<cnt;i++)
        {
            for(int j=1;j<n;j++)
            {
                if(OnSegment(V[i],p[j],p[j-1]))
                    e++;
            }
        }
        printf("Case %d: There are %d pieces.\n",++ca,e+2-cnt);
    }
    return 0;
}


你可能感兴趣的:(ACM,uva,计算几何)