zoukankan      html  css  js  c++  java
  • LA 3263 /// 欧拉定理 oj21860

    题目大意:

    n个端点的一笔画 第n个和第1个重合 即一笔画必定是闭合曲线

    输出平面被分成的区域数

    欧拉定理 V+F-E=2 即 点数+面数-边数=2 (这里的面数包括了外部)

    #include <bits/stdc++.h>
    using namespace std;
    
    const double eps=1e-10;
    double add(double a,double b) {
        if(abs(a+b)<eps*(abs(a)+abs(b))) return 0;
        return a+b;
    }
    struct P {
        double x,y;
        P(){}
        P(double _x,double _y):x(_x),y(_y){}
        P operator - (P p) {
            return P(add(x,-p.x),add(y,-p.y)); }
        P operator + (P p) {
            return P(add(x,p.x),add(y,p.y)); }
        P operator / (double d) {
            return P(x/d,y/d); }
        P operator * (double d) {
            return P(x*d,y*d); }
        double dot (P p) {
            return add(x*p.x,y*p.y); }
        double det (P p) {
            return add(x*p.y,-y*p.x); }
        bool operator <(const P& p)const {
            return x<p.x || (x==p.x && y<p.y);
        }
        bool operator ==(const P& p)const {
            return abs(x-p.x)<eps && abs(y-p.y)<eps;
        }
        void read(){
            scanf("%lf%lf",&x,&y); }
    }p[305], v[305*305], t;
    int n;
    
    bool onSeg(P a,P b,P c) {
        return (a-c).det(b-c)==0 && (a-c).dot(b-c)<=0;
    } /// c是否在线段ab上 包括端点
    bool onSeg2(P a,P b,P c) {
        return (a-c).det(b-c)==0 && (a-c).dot(b-c)<0;
    } /// c是否在线段ab上 不包括端点
    P ins(P a,P b,P c,P d)  {
        return a+(b-a)*((d-c).det(c-a)/(d-c).det(b-a));
    } /// 直线ab与cd的交点
    bool insSS(P a,P b,P c,P d) {
        if((a-b).det(c-d)==0) { // 平行
            return onSeg(a,b,c) || onSeg(a,b,d)
                ||  onSeg(c,d,a) || onSeg(c,d,b);
        }
        else {
            t=ins(a,b,c,d);
            return onSeg(a,b,t) && onSeg(c,d,t);
        }
    } /// 线段ab与cd是否相交
    
    int main()
    {
        int o=1;
        while(~scanf("%d",&n)) {
            if(n==0) break;
            for(int i=0;i<n;i++)
                p[i].read(), 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(insSS(p[i],p[i+1],p[j],p[j+1]))
                        v[c++]=t; /// 若相交 加入交点
    
            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(onSeg2(p[j],p[j+1],v[i]))
                        e++; /// 线段上一个非端点的点可以把一条线段分成两段 
    
            printf("Case %d: There are %d pieces.
    ",o++,e+2-c);
        }
    
        return 0;
    } //21860
  • 相关阅读:
    keep-alive的深入理解与使用(配合router-view缓存整个路由页面)
    vue无法自动打开浏览器
    解决vue页面刷新或者后退参数丢失的问题
    vue 跳转并传参,实现数据实时更新
    Struts2 有关于无法正常的使用通配符
    有关于java反编译工具的使用
    Action名称的搜索顺序
    Struts2 的 值栈和ActionContext
    在Action 中访问web资源
    oracle 创建database Link
  • 原文地址:https://www.cnblogs.com/zquzjx/p/9723405.html
Copyright © 2011-2022 走看看