zoukankan      html  css  js  c++  java
  • That Nice Euler Circuit UVALive

    欧拉定理:

    简单多面体的顶点数V、棱数E及面数F间有关系有著名的欧拉公式:V-E+F=2。

    设G为任意的连通的平面图,则v-e+f=2,v是G的顶点数,e是G的边数,f是G的面数。(

    证明(?)

    这题的做法就是模拟画线的过程,统计出画每一条线时与之前所有线的交点,将所有交点记录下来,将每一个顶点也记录下来。然后将点去重,得到点数。然后统计每一条线上有几个点,那么这条线就被分成了点数+1段,这样得到边数。最后根据公式算出面数。

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<algorithm>
      4 using namespace std;
      5 namespace X
      6 {
      7     const double eps=1e-10;
      8     struct Point
      9     {
     10         double x,y;
     11         Point(double x=0,double y=0):x(x),y(y){}
     12     };
     13     typedef Point Vec;
     14     Vec operator+(const Vec& a,const Vec& b)
     15     {
     16         return Vec(a.x+b.x,a.y+b.y);
     17     }
     18     Vec operator-(const Vec& a,const Vec& b)
     19     {
     20         return Vec(a.x-b.x,a.y-b.y);
     21     }
     22     Vec operator*(const double& a,const Vec& b)
     23     {
     24         return Vec(a*b.x,a*b.y);
     25     }
     26     Vec operator*(const Vec& a,const double& b)
     27     {
     28         return Vec(b*a.x,b*a.y);
     29     }
     30     Vec operator/(const Vec& a,const double& b)
     31     {
     32         return Vec(a.x/b,a.y/b);
     33     }
     34     int dcmp(double x)
     35     //正为1,负为-1,0为0
     36     {
     37         if(fabs(x)<eps)    return 0;
     38         return x<0?-1:1;
     39     }
     40     bool operator<(const Vec& a,const Vec& b)
     41     //人为规定的优先级
     42     {
     43         return a.x<b.x||(a.x==b.x&&a.y<b.y);
     44     }
     45     bool operator==(const Vec& a,const Vec& b)
     46     //判向量相等
     47     {
     48         return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
     49     }
     50     double dot(const Vec& a,const Vec& b)
     51     //点积
     52     {
     53         return a.x*b.x+a.y*b.y;
     54     }
     55     double cross(const Vec& a,const Vec& b)
     56     //叉积
     57     {
     58         return a.x*b.y-a.y*b.x;
     59     }
     60     double len(const Vec& x)
     61     //向量长度
     62     {
     63         return sqrt(dot(x,x));
     64     }
     65     double angle(const Vec& a,const Vec& b)
     66     //夹角,0~180°
     67     {
     68         return acos(dot(a,b)/len(a)/len(b));
     69     }
     70     double angle1(const Vec& a,const Vec& b)
     71     //夹角,带方向,a到b逆时针为正,顺时针为负,共线为0
     72     {
     73         return acos(dot(a,b)/len(a)/len(b))*(dcmp(cross(a,b)));
     74     }
     75     Vec rotate(const Vec& a,const double& rad)
     76     //旋转,正为逆时针,负为顺时针
     77     {
     78         return Vec(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
     79     }
     80     Vec normal(const Vec& x)
     81     //单位法线,左转90°后除以自身长度
     82     {
     83         double l=len(x);
     84         return Vec(-x.y/l,x.x/l);
     85     }
     86     Vec normal1(const Vec& x)
     87     //法线,不归一化
     88     {
     89         return Vec(-x.y,x.x);
     90     }
     91     Point lineline(const Point& p,const Vec& v,const Point& q,const Vec& w)
     92     //直线交点,GetLineIntersection
     93     {
     94         return p+v*cross(w,p-q)/cross(v,w);
     95     }
     96     double ptline(const Point& p,const Point& a,const Point& b)
     97     //point_to_line,点到直线距离,DistanceToLine
     98     {
     99         Vec v1=b-a,v2=p-a;
    100         return fabs(cross(v1,v2)/len(v1));
    101     }
    102     double ptseg(const Point& p,const Point& a,const Point& b)
    103     //point_to_segment,点到线段距离,DistanceToSegment
    104     {
    105         if(a==b)    return len(p-a);
    106         //Vec v1=b-a,v2=a-p,v3=p-b;
    107         Vec v1=b-a,v2=p-a,v3=p-b;
    108         if(dcmp(dot(v1,v2))<0)    return len(v2);
    109         else if(dcmp(dot(v1,v3))>0)    return len(v3);
    110         else return fabs(cross(v1,v2)/len(v1));
    111     }
    112     double area2(const Point& a,const Point& b,const Point& c)
    113     //叉积对应平行四边形的面积
    114     {
    115         return cross(b-a,c-a);
    116     }
    117     double thrarea(const Point& a,const Point& b,const Point& c)
    118     //三角形面积,绝对值
    119     {
    120         return fabs(cross(b-a,c-a)/2);
    121     }
    122     bool ifpar(const Vec& a,const Vec& b)
    123     //ifParallel
    124     //是否共线/平行
    125     {
    126         return dcmp(cross(a,b))==0;
    127     }
    128     Point pointline(const Point& p,const Point& a,const Vec& v)
    129     //点在直线上投影,GetLineProjection
    130     {
    131         return a+v*(dot(p-a,v)/dot(v,v));
    132     }
    133     bool ifsegseg(const Point& a1,const Point& a2,const Point& b1,const Point& b2)
    134     //SegmentProperIntersection,线段相交判定,不包含端点,不允许共线。有交点时求交点直接用直线交点即可
    135     //此处就是求两条线段的两个端点是否都分别在另一条线段的两侧
    136     {
    137         double c1=cross(a2-a1,b1-a1),c2=cross(a2-a1,b2-a1),
    138             c3=cross(b2-b1,a1-b1),c4=cross(b2-b1,a2-b1);
    139         return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
    140     }
    141     bool ifonseg(const Point& p,const Point& a1,const Point& a2)
    142     //OnSegment,点是否在线段上
    143     //这样就能判定向量p a1与p a2共线,且方向相反
    144     {
    145         return dcmp(cross(a1-p,a2-p))==0&&dcmp(dot(a1-p,a2-p))<0;
    146     }
    147     bool ifsegseg1(const Point& a1,const Point& a2,const Point& b1,const Point& b2)
    148     //线段相交判定,包含端点,允许共线
    149     {
    150         double c1=cross(a2-a1,b1-a1),c2=cross(a2-a1,b2-a1),
    151             c3=cross(b2-b1,a1-b1),c4=cross(b2-b1,a2-b1);
    152         return (dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0)||
    153         (dcmp(c1)==0&&dcmp(c2)==0)||ifonseg(a1,b1,b2)||
    154         ifonseg(a2,b1,b2)||ifonseg(b1,a1,a2)||ifonseg(b2,a1,a2);
    155     }
    156     double polyarea(Point p[],int n)
    157     //PolygonArea,有向面积,要求点按顺序能组成多边形(不会边相交,可以凹),如果顺时针转就是负,逆时针就是正(未验证)
    158     {
    159         double ans=0;
    160         for(int i=1;i<n-1;i++)
    161             ans+=cross(p[i]-p[0],p[i+1]-p[0]);
    162         return ans/2;
    163     }
    164 };
    165 using namespace X;
    166 Point p[310];
    167 Point p2[100000];
    168 int n,v,e,T;
    169 int main()
    170 {
    171     int i,j;
    172     scanf("%d",&n);
    173     while(n!=0)
    174     {
    175         v=0;e=n-1;
    176         scanf("%lf%lf",&p[1].x,&p[1].y);
    177         p2[++v]=p[1];
    178         for(i=2;i<=n;i++)
    179         {
    180             scanf("%lf%lf",&p[i].x,&p[i].y);p2[++v]=p[i];
    181             for(j=1;j<=i-2;j++)
    182             {
    183                 if(ifsegseg(p[i-1],p[i],p[j],p[j+1]))
    184                     p2[++v]=lineline(p[i-1],p[i]-p[i-1],p[j],p[j+1]-p[j]);
    185             }
    186         }
    187         sort(p2+1,p2+v+1);
    188         v=unique(p2+1,p2+v+1)-p2-1;
    189         for(i=1;i<n;i++)
    190             for(j=1;j<=v;j++)
    191                 if(ifonseg(p2[j],p[i],p[i+1]))
    192                     e++;
    193         printf("Case %d: There are %d pieces.
    ",++T,e+2-v);
    194         scanf("%d",&n);
    195     }
    196     return 0;
    197 }
  • 相关阅读:
    app测试的一些较为重要的测试点
    adb工作常用命令
    vue中$attrs $listeners你会用吗?
    Vue中组件通信的常用方式
    Vue中watch 的用法
    VUE中使用 async await 将 axios 异步请求同步化处理
    安装spyder记录
    树莓CM3开机连接WIFI
    树莓派搭建seafile服务器备忘
    关于JAVA数据结构_线性表(通过单向链表实现)的学习
  • 原文地址:https://www.cnblogs.com/hehe54321/p/7768881.html
Copyright © 2011-2022 走看看