That Nice Euler Circuit (好看的一笔画)

直接就是欧拉定理:设平面图的顶点数为,边数,和面数分别为V,E和F,则V+ F-E=2;

所以就只需要算顶点数和边数就好了。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<iostream>
#include<complex>
#include<string>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define nn 330
#define LL long long
#define ULL unsiged long long
#define mod 0x7fffffff
#define inf oxfffffffffff
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1

        ((`'-"`  `""-'`))
         ) -  -  (
        /  (o _ o)  \
        \  ( 0 )  /
       _'-.._ '=' _..-'_
      /`;#'#'#. -. #'#'#;`\
      \_))   '#'   ((_/
      #.  ☆ ☆ ☆  .#
      '#.  求 A C!  .#'
       /'#.     .#'\
       _\\'#.   .#'//_
       (((___)'#'(___)))

struct node
{
    double x,y;
    node(double x=0,double y=0):x(x),y(y){}
};
typedef node point;
point operator + (node A,node B)//加
{
    return point(A.x+B.x,A.y+B.y);
}
point operator - (node A,node B)//减
{
    return point(A.x-B.x,A.y-B.y);
}
point operator * (node A,double p)//数乘
{
    return point(A.x*p,A.y*p);
}
point operator / (node A,double p)//除
{
    return point(A.x/p,A.y/p);
}
bool operator < (const point& A,const point& B)//比较大小
{
    return A.x<B.x||(A.x==B.x&&A.y<B.y);
}
const double eps=1e-10;
int dcmp(double x)
{
    if(fabs(x)<eps)     return 0;
    else    return x<0?-1:1;
}
bool operator == (const point& a,const point& b)//比较是不是同一点
{
    return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;
}
double dot(node A,node B)//点积
{
    return A.x*B.x+A.y*B.y;
}
double length(node A)//长度
{
    return sqrt(dot(A,A));
}
double angle(node A,node B)//夹角
{
    return acos(dot(A,B) / length(A)/length(B));
}
double cross(node A,node B)//叉积
{
    return A.x*B.y-A.y*B.x;
}
point Rotate(point A,double rad)//旋转rad角度
{
    return point(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
point normal(point A)//旋转90的情况
{
    double L=length(A);
    return point(-A.y/L,A.x/L);
}
point gli(point P,point V,point Q,point W)//求直线P+Vt和直线Q+Wt的交点
{
    point u=P-Q;
    double t=cross(W,u)/cross(V,W);
    return P+V*t;
}
point distl(point p,point a,point b)//点p到a,b所表示直线的距离
{
    point v1=b-a,v2=p-a;
    return fabs(cross(v1,v2)/length(v1));
}
point dists(point p,point a,point b)//点p到线段ab的距离
{
    if(a==b) return length(p-a);
    point v1=b-a,v2=p-a,v3=p-b;
    if(dcmp(dot(v1,v2))<0)  return length(v2);
    else if(dcmp(dot(v1,v2))>0) return length(v3);
    else return fabs(cross(v1,v2)/length(v1));
}
point getlp(point P,point A,point B)//点到直线的投影
{
    point v=B-A;
    return A+v*(dot(v,P-A)/dot(v,v));
}
bool segpi(point a1,point a2,point b1,point b2)//判断线段相交
{
    double c1=cross(a2-a1,b1-a1);
    double c2=cross(a2-a1,b2-a1);
    double c3=cross(b2-b1,a1-b1);
    double c4=cross(b2-b1,a2-b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
bool ons(point p,point a1,point a2)//判断点是否在线段上
{
    return dcmp(cross(a1-p,a2-p))==0 && dcmp(dot(a1-p,a2-p))<0;
}
point p[nn],v[nn*nn];
int main()
{
    int n,kcae=1;
    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(segpi(p[i],p[i+1],p[j],p[j+1]))
                    v[c++]=gli(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(ons(v[i],p[j],p[j+1]))
                    e++;
            }
        }
        printf("Case %d: There are %d pieces.\n",kcae++,e+2-c);
    }
    return 0;
}

//  ...|||||||||||||||∞ |||||
//     ╭||||━━  ━━   ||||╮
//     ╰|||  ~   |||╯
//      ||╰╭--╮ˋ╭--╮╯||
//      || ╰/ /  \ \╯|| ОО

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值