• codeforces 23D Tetragon 计算几何


    题意:给你三条相等的边的中点,问是否存在这样的凸四边形

    思路:因为答案是四边形,所以这三条边肯定是连续的,我们枚举中间那条边。

    不妨设中间的边的两个端点分别为p和q,其中点为b,相邻两边的中点为a和c。

    则显然,p必须在线段ab的垂直平分线上,q必须在线段bc的垂直平分线上。

    #include <iostream>
    #include <math.h>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define eps 1e-8
    struct point
    {
        double x,y;
        point()
        {
            x=y=0;
        }
        point(double xx,double yy)
        {
            x=xx;
            y=yy;
        }
    } p[3],ans[4],w[4];
    int top;
    double dist(point a,point b)
    {
        return hypot(fabs(a.x-b.x),fabs(a.y-b.y));
    }
    double Mul(point a,point b,point c)
    {
        return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
    }
    int cmp(const void *a,const void *b)
    {
        point c=*(point *)a;
        point d=*(point *)b;
        double k=Mul(ans[0],c,d);
        if(k<0||(!k&&dist(c,ans[0])>dist(d,ans[0]))) return 1;
        return -1;
    }
    //凸包模板
    void con()
    {
        int i;
        int n=4;
        for(i=1;i<n;i++)
        {
            point temp;
            if(ans[i].y<ans[0].y||(ans[i].y==ans[0].y&&ans[i].x<ans[0].x))
            {
                temp=ans[i];
                ans[i]=ans[0];
                ans[0]=temp;
            }
        }
        qsort(ans+1,n-1,sizeof(ans[0]),cmp);
        w[0]=ans[0];
        w[1]=ans[1];
        w[2]=ans[2];
        top=2;
        for(i=3;i<n;i++)
        {
            while(top>=2&&Mul(w[top-1],w[top],ans[i])<=0) top--;
            top++;
            w[top]=ans[i];
        }
    }
    bool TB()
    {
        top=0;
        con();
        int i,j,k;
        if(top==3)
        {
            for(i=0;i<=3;i++)
            {
                for(j=0;j<=3;j++)
                {
                    for(k=0;k<=3;k++)
                    {
                        if(i==j||i==k||j==k) continue;
                        //三点不在一条直线上
                        if(fabs((w[j].y-w[i].y)*(w[j].x-w[k].x)-(w[j].y-w[k].y)*(w[j].x-w[i].x))<eps) return 0;
                    }
                }
            }
            double dis[5];
            for(i=0;i<4;i++)
                dis[i]=dist(w[i],w[(i+1)%4]);
            sort(dis,dis+4);
            int tp1=0,tp2=0;
            for(i=0;i<4;i++)
            {
                if(fabs(dis[i]-dis[0])<eps) tp1++;
                if(fabs(dis[i]-dis[3])<eps) tp2++;
            }
            if(tp1>=3||tp2>=3) return 1;
            return 0;
        }
        return 0;
    }
    int solve(point b,point a,point c)
    {
        double k1,k2;
        point d=point((a.x+b.x)/2,(a.y+b.y)/2);
        point e=point((c.x+b.x)/2,(c.y+b.y)/2);
        if(fabs(a.y-b.y)<eps)
        {
            if(fabs(c.y-b.y)<eps) return 0;
            else
            {
                k2=-(c.x-b.x)/(c.y-b.y);
                double uy=-(k2*(2*b.x-d.x-e.x)+e.y-2*b.y);
                ans[0]=point(d.x,uy);
                ans[1]=point(2*b.x-d.x,2*b.y-uy);
                ans[2]=point(2*c.x-ans[1].x,2*c.y-ans[1].y);
                ans[3]=point(2*a.x-ans[0].x,2*a.y-ans[0].y);
                return TB();
            }
        }
        else
        {
            k1=-(a.x-b.x)/(a.y-b.y);
            if(fabs(c.y-b.y)<eps)
            {
                double ux=2*b.x-e.x;
                ans[0]=point(ux,k1*(ux-d.x)+d.y);
                ans[1]=point(2*b.x-ux,2*b.y-k1*(ux-d.x)-d.y);
                ans[2]=point(2*c.x-ans[1].x,2*c.y-ans[1].y);
                ans[3]=point(2*a.x-ans[0].x,2*a.y-ans[0].y);
                return TB();
            }
            else
            {
                k2=-(c.x-b.x)/(c.y-b.y);
                if(fabs(k1-k2)<eps) return 0;
                double ux=-k1*d.x+2*k2*b.x-k2*e.x+e.y+d.y-2*b.y;
                ux/=(k2-k1);
                ans[0]=point(ux,k1*(ux-d.x)+d.y);
                ans[1]=point(2*b.x-ux,2*b.y-k1*(ux-d.x)-d.y);
                ans[2]=point(2*c.x-ans[1].x,2*c.y-ans[1].y);
                ans[3]=point(2*a.x-ans[0].x,2*a.y-ans[0].y);
                return TB();
            }
        }
    }
    int main()
    {
        int T,i,j,k,m,n,flag;
        point a,b,c;
        scanf("%d",&T);
        while(T--)
        {
            for(i=0; i<3; i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            flag=0;
            for(i=0; i<3; i++)
            {
                b=p[i];
                a=p[(i+1)%3];
                c=p[(i+2)%3];
                if(solve(b,a,c))
                {
                    flag=1;
                    break;
                }
            }
            if(flag)
            {
                printf("YES
    ");
                for(i=0; i<4; i++)
                    printf("%.10f %.10f ",w[i].x,w[i].y);
                printf("
    ");
            }
            else printf("NO
    
    ");
        }
        return 0;
    }
  • 相关阅读:
    如何解决selenium打开chrome提示chromedriver.exe已停止工作
    移动端弱网测试 fiddle
    android 真机设备识别不出adb interface
    网络基础知识
    《Mongo权威指南》学习手记
    MongoDB数据库备份
    windows下安装mongoDB(zip版)
    ubuntu apt
    docker 免sudo设置(仅3个命令)
    ubuntu18.04双卡机安装ubidia驱动遇到的坑
  • 原文地址:https://www.cnblogs.com/zuferj115/p/5328895.html
Copyright © 2020-2023  润新知