zoukankan      html  css  js  c++  java
  • ZOJ 3495 Lego Bricks

    计算几何,暴力。

    题目中有一句话:$The$ $mass$ $of$ $each$ $brick$ $is$ $equally$ $distributed$ $and$ $it$ $will$ $be$ $stable$ $if$ $it$ $is$ $placed$ $on$ $bases$ $or$ $stable$ $bricks$ $and$ $the$ $moment$ $of$ $it$ $can$ $be$ $zero$ $when$ $it$ $is$ $placed$. 

    核心原则:左右半段均有稳定的东西支撑,这条才算是稳定的。暴力扩展就可以了。需要用到判断线段不严格相交以及点到线段的最小距离。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0);
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar();
        x = 0;
        while(!isdigit(c)) c = getchar();
        while(isdigit(c))
        {
            x = x * 10 + c - '0';
            c = getchar();
        }
    }
    
    
    const double eps=1e-10;
    #define zero(x)(((x)>0?(x):(-x))<eps)
    
    struct point
    {
        double x,y;
        point(double X,double Y)
        {
            x=X;
            y=Y;
        }
    };
    
    double xmult(point p1,point p2,point p0)
    {
        return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    }
    
    int dots_inline(point p1,point p2,point p3)
    {
        return zero(xmult(p1,p2,p3));
    }
    
    int same_side(point p1,point p2,point l1,point l2)
    {
        return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;
    }
    
    int dot_online_in(point p,point l1,point l2)
    {
        return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
    }
    
    int intersect_in(point u1,point u2,point v1,point v2)
    {
        if(!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2)) return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);
        return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);
    }
    
    int T;
    struct YUAN
    {
        double x,y,r;
    } yuan[200];
    struct XIAN
    {
        double p1x,p1y,p2x,p2y;
    } xian[200];
    int n,m;
    
    int f[200];
    
    double DIS(point a,point b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    point intersection(point u1,point u2,point v1,point v2)
    {
        point ret=u1;
        double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
                 /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
        ret.x+=(u2.x-u1.x)*t;
        ret.y+=(u2.y-u1.y)*t;
        return ret;
    }
    
    point ptoseg(point p,point l1,point l2)
    {
        point t=p;
        t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;
        if(xmult(l1,t,p)*xmult(l2,t,p)>eps)
            return DIS(p,l1)<DIS(p,l2)?l1:l2;
        return intersection(p,t,l1,l2);
    }
    
    int check(point A,point B,int b)
    {
        point F=ptoseg(point(yuan[b].x,yuan[b].y),A,B);
        double dis=DIS(F,point(yuan[b].x,yuan[b].y));
        if(dis<=yuan[b].r) return 1;
        return 0;
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++) scanf("%lf%lf%lf",&yuan[i].x,&yuan[i].y,&yuan[i].r);
            for(int i=1; i<=m; i++) scanf("%lf%lf%lf%lf",&xian[i].p1x,&xian[i].p1y,&xian[i].p2x,&xian[i].p2y);
    
            memset(f,0,sizeof f);
    
            int sum=0;
            while(1)
            {
                int Z=0;
    
                for(int i=1; i<=m; i++)
                {
                    if(f[i]==1) continue;
    
                    point p1= point(xian[i].p1x,xian[i].p1y);
                    point p2= point(xian[i].p2x,xian[i].p2y);
                    point p3= point((p1.x+p2.x)/2,(p1.y+p2.y)/2);
    
                    int f1=0,f2=0;
    
                    for(int j=1; j<=n; j++)
                    {
                        if(check(p1,p3,j)) f1=1;
                        if(check(p2,p3,j)) f2=1;
                    }
    
                    for(int j=1; j<=m; j++)
                    {
                        if(f[j]==0) continue;
    
                        if(intersect_in(p1,p3,point(xian[j].p1x,xian[j].p1y),point(xian[j].p2x,xian[j].p2y))) f1=1;
                        if(intersect_in(p2,p3,point(xian[j].p1x,xian[j].p1y),point(xian[j].p2x,xian[j].p2y))) f2=1;
                    }
    
                    if(f1==1&&f2==1) f[i]=1,Z++;
                }
    
                if(Z==0) break;
                sum=sum+Z;
            }
    
            if(sum!=m) printf("NO
    ");
            else printf("YES
    ");
    
        }
        return 0;
    }
  • 相关阅读:
    待解决的问题
    Java编译环境的搭建(eclipse)
    Ubuntu升级没有声音的解决方法
    Ubuntu中文输入法的添加
    apue和error
    韦东山linux学习之ubuntu 9.10 软件源 问题
    查询表的列名
    事务管理
    数组 String[]
    java 内存
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6384482.html
Copyright © 2011-2022 走看看