poj2284 That Nice Euler Circuit(欧拉定理+枚举)

来源:互联网 发布:ubuntu ntp设置 编辑:程序博客网 时间:2024/05/24 00:34

欧拉定理:V+F-E=2

V的求法:将原有的拐点、线段不在端点处的的交点同一排序、去重,留下的点数就是V

E的求法:原有线段数+新被分割出的,枚举点和线段,若点在线段上,新被分割出的就多一条


注意:eps设为1e-13挂了,设为1e-10就AC

虽然A了但其实是有问题的

比如(3.333333333333333,6.0000000)

   与 (3.333333333333333,7.0000000)

   与 (3.333333333333334,6.0000000)

若eps设为1e-10,第三个点就被第一个点消掉了

但eps太小,可能算点积和叉积的误差不能被忽略。。。

精度坑死人呐


代码

#include<stdio.h>#include<stdlib.h>#include<math.h>#define eps 1e-13struct Point{double x,y;Point(){x=y=0;}};typedef Point Vector;Point P[305],V[100005];Vector operator + (Vector a,Vector b){a.x+=b.x;a.y+=b.y;return a;}Vector operator - (Vector a,Vector b){a.x-=b.x;a.y-=b.y;return a;}Vector operator * (Vector a,double b){a.x*=b;a.y*=b;return a;}int dcmp(double x){if(x<=eps&&x>=-eps) return 0;if(x>0) return 1;return -1;}bool operator ==(Point a,Point b){return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;}bool operator < (Point a,Point b){return dcmp(a.x-b.x)==-1 || (dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==-1);}bool operator > (Point a,Point b){return dcmp(a.x-b.x)==1 || (dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==1);}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-b.x*a.y;}bool jiao(Point a,Point b,Point c,Point d){double c1=Cross(b-a,c-a),c2=Cross(b-a,d-a),c3=Cross(d-c,a-c),c4=Cross(d-c,b-c);return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;}Point jiaodian(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 PointOnLine(Point p,Point a,Point b){return dcmp(Cross(p-a,p-b))==0 && dcmp(Dot(p-a,p-b))==-1;}void jh(Point& a,Point& b){Point t=a;a=b;b=t;}void kp(int low,int high){int i=low,j=high;Point mid=V[(i+j)/2];while(i<j){while(V[i]<mid) i++;while(V[j]>mid) j--;if(i<=j){jh(V[i],V[j]);i++;j--;}}if(j>low) kp(low,j);if(i<high) kp(i,high);}int main(){int T=0,n,i,j,v,e;while(scanf("%d",&n)&&n>0){T++;for(i=1;i<=n;i++){scanf("%lf%lf",&P[i].x,&P[i].y);V[i]=P[i];}v=e=n-1;for(i=1;i<n-1;i++)for(j=i+1;j<n;j++)if(jiao(P[i],P[i+1],P[j],P[j+1])) V[++v]=jiaodian(P[i],P[i+1]-P[i],P[j],P[j+1]-P[j]);kp(1,v);j=0;for(i=1;i<=v;i++)if(i==1||!(V[i]==V[i-1])) V[++j]=V[i];v=j;for(i=1;i<=v;i++)for(j=1;j<n;j++)if(PointOnLine(V[i],P[j],P[j+1])) e++;printf("Case %d: There are %d pieces.\n",T,e-v+2);}return 0;}


0 0