That Nice Euler Circuit UVALive - 1342

欧拉定理:边数-点数+2=面数,因此转化问题为求边数和点数,用到计算几何的知识

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>

using namespace std;


struct Node{
    double x,y;
    Node(double x=0,double y=0) :x(x),y(y) { }
};
bool operator <(const Node&a,const Node&b){
    return a.x<b.x || (a.x==b.x&&a.y<b.y);
}
typedef Node Vector;
Vector operator - (Node A,Node B) {
    return Vector(A.x-B.x,A.y-B.y);
}
Vector operator * (Vector A,double b){
    return Vector(A.x*b,A.y*b);
}
Vector operator + (Vector A,Vector p){
    return Node(A.x+p.x,A.y+p.y);
}
const double eps=1e-10;
int dcmp(double x){
    if(fabs(x)<eps) return 0;
    return x<0 ?-1:1;
}
bool operator ==(const Node&a,const Node&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 Cross(Vector A,Vector B) { 
    return A.x*B.y-A.y*B.x;
}
Node GetLineIntersection(Node P,Vector v,Node Q,Vector w)
{
    Vector u=P-Q;
    double t=Cross(w,u)/Cross(v,w);
    return P+v*t;
}
bool SegmentProperIntersection(Node a1,Node a2,Node b1,Node 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(Node p,Node a1,Node a2)
{
    return dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dot(a1-p,a2-p))<0;
}
const int N=300+5;
Node a[N],b[N*N];

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

 

unique竟然用错了!纠正了好长时间

 

posted @ 2019-02-14 14:59  mgnfcnt  阅读(132)  评论(0编辑  收藏  举报