LA 3263 - That Nice Euler Circuit(计算几何基础题目 欧拉公式)

题目链接

3263 - That Nice Euler Circuit

分析

这是紫书上的模板题,唯一有点思维的地方是用到欧拉公式,关于欧拉公式的简单证明可以看这篇blog

AC code

#include
#define pb push_back
#define mp make_pair
#define PI acos(-1)
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define INF64 0x3f3f3f3f3f3f3f3f
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define ms(x,v) memset((x),(v),sizeof(x))
#define eps 1e-10
#define dcmp(x) (fabs(x) < eps? 0:((x) <0?-1:1))
using namespace std;
typedef long long LL;
typedef long double DB;
typedef pair<int,int> Pair;
const int maxn = 300+10;
struct Point{
    double x,y;
    Point(double _x=0,double _y=0):x(_x),y(_y){}
    void print(){
        std::cout << x <<" " <'\n';
    }
    bool operator < (const Point & p)
    {
        return x < p.x || (x == p.x && y < p.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 a){return Vector(a*A.x,a*A.y);}
Vector operator / (Vector A,double p){return A*(1/p);}
bool operator == (const Point A,const Point  B){return !dcmp(A.x-B.x) && !dcmp(A.y-B.y);}
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));}
Vector Rotate(Vector &A,double rad){return Vector(A.x*cos(rad)-sin(rad)*A.y,A.x*sin(rad)+A.y*cos(rad));}
Vector Normal(Vector A){//A 的单位法向量
    double L = Length(A);
    return Vector(-A.y/L,A.x/L);
}
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);}

Point GetLineIntersection(Point P,Vector  v, Point  Q,Vector w){
    //计算交点,当v,w平行时无效
    Point u = P-Q;
    double t = Cross(v,u) / Cross(v,w);
    return Q+w*t;
}
double Dis2Line(Point &P,Point & A,Point & B){
    //点p到A,B的距离
    Vector u1 = P-A;
    Vector u2 = B-A;
    return abs(Cross(u1,u2)/Length(u2));
}
Point GetLineProjection(Point &P,Point &A,Point & B){
    //the projection Point Q of P to Line A,B;
    Vector v = B-A;
    return A+ v*(Dot(v,P-A)/Dot(v,v));
}
bool SegInsertion(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 dcmp(c1)*dcmp(c2) <0 && dcmp(c3)*dcmp(c4) <0;
}
bool onSegment(Point  P,Point A,Point B){
    return dcmp(Cross(A-P,B-P))==0 && dcmp(Dot(A-P,B-P)) <0;
}

//多边形

double polygonArea(Point *p,int n){
    double area =0;
    for(int i=1 ; i1 ; ++i)
        area += Cross(p[i]-p[0],p[i+1]-p[0]);
    return area/2;
}
const int N = 305;
Point p[N],V[N*N];
int main()
{
    int n;
    int kase = 0;
    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--;
        int c = n,e = n;
        for(int i = 0;i < n;i++)
            for(int j = i+1;j < n;j++)
                if(SegInsertion(p[i],p[i+1],p[j],p[j+1]))
                    V[c++] = GetLineIntersection(p[i],p[i+1]-p[i],p[j],p[j+1]-p[j]);

        sort(V,V+c);
        c = unique(V,V+c) - V;
        for(int i = 0;i < c;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",++kase,e+2-c);
    }
    return 0;
}

你可能感兴趣的:(算法刷题)