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竟然用错了!纠正了好长时间