Gym 100499H - cctv - 计算几何

来源:互联网 发布:ubuntu snmp 配置 编辑:程序博客网 时间:2024/06/05 00:30

题目大致意思是一个矩形,里面有很多小矩形,小矩形是障碍物,问在四个角上能看到的范围面积。

解题思路:

因为障碍物只有20个所以取出每个三角形靠近观望点的三个点。然后将这些点去重排序。然后这些点将这个90度角分割开。对于每个区间暴力枚举所有边,看那条边和这个角组成的三角形最小保存。最后将这些值相加即可。

基本思路可以概括为将可见范围划分成许多由一个角和对应边组成的三角形来求面积。

#include <bits/stdc++.h>using namespace std;#define pi acos(-1)double ex1[1000],ey1[1000],ex2[1000],ey2[1000];double jiao[1000];int vis[1000];double vmax[1000];struct EDGE {    double h;    int fa;    double c1,c2;}edge[1000];int main(){    //freopen("test.in","r",stdin);    double pp=180.0/pi;    double ans1,ans2,ans3,ans4;    int t;    double x1,x2,y1,y2;    int en,em;    int n,m,nn;    int p;    int sa;    scanf("%d",&t);    while(t--) {
        scanf("%d%d%d",&en,&em,&p);        for(int i=1;i<=p;i++)            scanf("%lf%lf%lf%lf",&ex1[i],&ey1[i],&ex2[i],&ey2[i]);        n=en;m=em;
<span style="white-space:pre"></span>/**这里是以左下角为例求面积**/        sa=1;                                                                       // 判断是否直接由矩形覆盖观望点。        for(int i=1;i<=p;i++) {            x1=ex1[i];x2=ex2[i];y1=ey1[i];y2=ey2[i];<span style="white-space:pre"></span>  //  建边和建角            if(x1==0&&y1==0) {                sa=0;                break;            }            edge[i*2-1].h=x1;            edge[i*2-1].fa=1;            edge[i*2].h=y1;            edge[i*2].fa=0;            if(x1!=0) edge[i*2-1].c1=atan(y1/x1)*pp; else edge[i*2-1].c1=90.0;            if(x1!=0) edge[i*2-1].c2=atan(y2/x1)*pp; else edge[i*2-1].c2=90.0;            if(x2!=0) edge[i*2].c1=atan(y1/x2)*pp; else edge[i*2].c1=90.0;            if(x1!=0) edge[i*2].c2=atan(y1/x1)*pp; else edge[i*2].c2=90.0;            jiao[i*3-2]=edge[i*2-1].c1;            jiao[i*3-1]=edge[i*2-1].c2;            jiao[i*3]=edge[i*2].c1;        }        jiao[p*3+1]=0.0;<span style="white-space:pre"></span>//将边界的边和0度,45度,90度加入        jiao[p*3+2]=90;        jiao[p*3+3]=45.0;        nn=p*3+3;        edge[p*2+1].h=n;        edge[p*2+1].c1=0.0;        edge[p*2+1].c2=45.0;        edge[p*2+1].fa=1;        edge[p*2+2].h=m;        edge[p*2+2].c1=45.0;        edge[p*2+2].c2=90.0;        edge[p*2+2].fa=0;        sort(jiao+1,jiao+nn+1);        for(int i=1;i<=nn;i++) {                                  //  去重            for(int j=i+1;j<=nn;j++) {                if(fabs(jiao[i]-jiao[j])<1e-9) {                    for(int k=j;k<nn;k++)                        jiao[k]=jiao[k+1];                    j--;                    nn--;                }            }        }        memset(vis,0,sizeof(vis));        for(int i=1;i<=nn;i++) {            vmax[i]=99999999.0;        }        for(int i=1;i<nn;i++) {<span style="white-space:pre"></span>//暴力枚举求最小面积            double gg1=jiao[i];            double gg2=jiao[i+1];            for(int j=1;j<=p*2+2;j++) {                if(edge[j].h!=0&&edge[j].c1<=gg1&&edge[j].c2>=gg2) {                    double ss;                    if(gg1==0.0) {                        ss=edge[j].h*tan(gg2/pp)*edge[j].h/2.0;                    }                    if(gg2==90.0) {                        ss=edge[j].h/tan(gg1/pp)*edge[j].h/2.0;                    }                    if(gg1!=0.0&&gg2!=90.0) {                        if(edge[j].fa==0) ss=fabs(edge[j].h/tan(gg2/pp)-edge[j].h/tan(gg1/pp))*edge[j].h/2.0;                        else ss=fabs(edge[j].h*tan(gg2/pp)-edge[j].h*tan(gg1/pp))*edge[j].h/2.0;                    }                    if(ss<vmax[i]) {                        vmax[i]=ss;                        vis[i]=j;                    }                }            }        }        ans3=0;        for(int i=1;i<nn;i++) {            ans3+=vmax[i];        }        if(sa==0) ans3=0;<span style="white-space:pre"></span>/**以上为以左下角为例之后为重复代码求其他点,只是将输出坐标进行了转换**/        sa=1;        for(int i=1;i<=p;i++) {            x1=ex1[i];x2=ex2[i];y2=m-ey1[i];y1=m-ey2[i];            if(x1==0&&y1==0) {                sa=0;                break;            }            edge[i*2-1].h=x1;            edge[i*2-1].fa=1;            edge[i*2].h=y1;            edge[i*2].fa=0;            if(x1!=0) edge[i*2-1].c1=atan(y1/x1)*pp; else edge[i*2-1].c1=90.0;            if(x1!=0) edge[i*2-1].c2=atan(y2/x1)*pp; else edge[i*2-1].c2=90.0;            if(x2!=0) edge[i*2].c1=atan(y1/x2)*pp; else edge[i*2].c1=90.0;            if(x1!=0) edge[i*2].c2=atan(y1/x1)*pp; else edge[i*2].c2=90.0;            jiao[i*3-2]=edge[i*2-1].c1;            jiao[i*3-1]=edge[i*2-1].c2;            jiao[i*3]=edge[i*2].c1;        }        jiao[p*3+1]=0.0;        jiao[p*3+2]=90;        jiao[p*3+3]=45.0;        nn=p*3+3;        edge[p*2+1].h=n;        edge[p*2+1].c1=0.0;        edge[p*2+1].c2=45.0;        edge[p*2+1].fa=1;        edge[p*2+2].h=m;        edge[p*2+2].c1=45.0;        edge[p*2+2].c2=90.0;        edge[p*2+2].fa=0;        sort(jiao+1,jiao+nn+1);        for(int i=1;i<=nn;i++) {            for(int j=i+1;j<=nn;j++) {                if(fabs(jiao[i]-jiao[j])<1e-9) {                    for(int k=j;k<nn;k++)                        jiao[k]=jiao[k+1];                    j--;                    nn--;                }            }        }        memset(vis,0,sizeof(vis));        for(int i=1;i<=nn;i++) {            vmax[i]=99999999.0;        }        for(int i=1;i<nn;i++) {            double gg1=jiao[i];            double gg2=jiao[i+1];            for(int j=1;j<=p*2+2;j++) {                if(edge[j].h!=0&&edge[j].c1<=gg1&&edge[j].c2>=gg2) {                    double ss;                    if(gg1==0.0) {                        ss=edge[j].h*tan(gg2/pp)*edge[j].h/2.0;                    }                    if(gg2==90.0) {                        ss=edge[j].h/tan(gg1/pp)*edge[j].h/2.0;                    }                    if(gg1!=0.0&&gg2!=90.0) {                        if(edge[j].fa==0) ss=fabs(edge[j].h/tan(gg2/pp)-edge[j].h/tan(gg1/pp))*edge[j].h/2.0;                        else ss=fabs(edge[j].h*tan(gg2/pp)-edge[j].h*tan(gg1/pp))*edge[j].h/2.0;                    }                    if(ss<vmax[i]) {                        vmax[i]=ss;                        vis[i]=j;                    }                }            }        }        ans1=0;        for(int i=1;i<nn;i++) {            ans1+=vmax[i];        }        if(sa==0) ans1=0;        sa=1;        for(int i=1;i<=p;i++) {            x2=n-ex1[i];x1=n-ex2[i];y2=m-ey1[i];y1=m-ey2[i];            if(x1==0&&y1==0) {                sa=0;                break;            }            edge[i*2-1].h=x1;            edge[i*2-1].fa=1;            edge[i*2].h=y1;            edge[i*2].fa=0;            if(x1!=0) edge[i*2-1].c1=atan(y1/x1)*pp; else edge[i*2-1].c1=90.0;            if(x1!=0) edge[i*2-1].c2=atan(y2/x1)*pp; else edge[i*2-1].c2=90.0;            if(x2!=0) edge[i*2].c1=atan(y1/x2)*pp; else edge[i*2].c1=90.0;            if(x1!=0) edge[i*2].c2=atan(y1/x1)*pp; else edge[i*2].c2=90.0;            jiao[i*3-2]=edge[i*2-1].c1;            jiao[i*3-1]=edge[i*2-1].c2;            jiao[i*3]=edge[i*2].c1;        }        jiao[p*3+1]=0.0;        jiao[p*3+2]=90;        jiao[p*3+3]=45.0;        nn=p*3+3;        edge[p*2+1].h=n;        edge[p*2+1].c1=0.0;        edge[p*2+1].c2=45.0;        edge[p*2+1].fa=1;        edge[p*2+2].h=m;        edge[p*2+2].c1=45.0;        edge[p*2+2].c2=90.0;        edge[p*2+2].fa=0;        sort(jiao+1,jiao+nn+1);        for(int i=1;i<=nn;i++) {            for(int j=i+1;j<=nn;j++) {                if(fabs(jiao[i]-jiao[j])<1e-9) {                    for(int k=j;k<nn;k++)                        jiao[k]=jiao[k+1];                    j--;                    nn--;                }            }        }        memset(vis,0,sizeof(vis));        for(int i=1;i<=nn;i++) {            vmax[i]=99999999.0;        }        for(int i=1;i<nn;i++) {            double gg1=jiao[i];            double gg2=jiao[i+1];            for(int j=1;j<=p*2+2;j++) {                if(edge[j].h!=0&&edge[j].c1<=gg1&&edge[j].c2>=gg2) {                    double ss;                    if(gg1==0.0) {                        ss=edge[j].h*tan(gg2/pp)*edge[j].h/2.0;                    }                    if(gg2==90.0) {                        ss=edge[j].h/tan(gg1/pp)*edge[j].h/2.0;                    }                    if(gg1!=0.0&&gg2!=90.0) {                        if(edge[j].fa==0) ss=fabs(edge[j].h/tan(gg2/pp)-edge[j].h/tan(gg1/pp))*edge[j].h/2.0;                        else ss=fabs(edge[j].h*tan(gg2/pp)-edge[j].h*tan(gg1/pp))*edge[j].h/2.0;                    }                    if(ss<vmax[i]) {                        vmax[i]=ss;                        vis[i]=j;                    }                }            }        }        ans2=0;        for(int i=1;i<nn;i++) {            ans2+=vmax[i];        }        if(sa==0) ans2=0;        sa=1;        for(int i=1;i<=p;i++) {            x2=n-ex1[i];x1=n-ex2[i];y1=ey1[i];y2=ey2[i];            if(x1==0&&y1==0) {                sa=0;                break;            }            edge[i*2-1].h=x1;            edge[i*2-1].fa=1;            edge[i*2].h=y1;            edge[i*2].fa=0;            if(x1!=0) edge[i*2-1].c1=atan(y1/x1)*pp; else edge[i*2-1].c1=90.0;            if(x1!=0) edge[i*2-1].c2=atan(y2/x1)*pp; else edge[i*2-1].c2=90.0;            if(x2!=0) edge[i*2].c1=atan(y1/x2)*pp; else edge[i*2].c1=90.0;            if(x1!=0) edge[i*2].c2=atan(y1/x1)*pp; else edge[i*2].c2=90.0;            jiao[i*3-2]=edge[i*2-1].c1;            jiao[i*3-1]=edge[i*2-1].c2;            jiao[i*3]=edge[i*2].c1;        }        jiao[p*3+1]=0.0;        jiao[p*3+2]=90;        jiao[p*3+3]=45.0;        nn=p*3+3;        edge[p*2+1].h=n;        edge[p*2+1].c1=0.0;        edge[p*2+1].c2=45.0;        edge[p*2+1].fa=1;        edge[p*2+2].h=m;        edge[p*2+2].c1=45.0;        edge[p*2+2].c2=90.0;        edge[p*2+2].fa=0;        sort(jiao+1,jiao+nn+1);        for(int i=1;i<=nn;i++) {            for(int j=i+1;j<=nn;j++) {                if(fabs(jiao[i]-jiao[j])<1e-9) {                    for(int k=j;k<nn;k++)                        jiao[k]=jiao[k+1];                    j--;                    nn--;                }            }        }        memset(vis,0,sizeof(vis));        for(int i=1;i<=nn;i++) {            vmax[i]=99999999.0;        }        for(int i=1;i<nn;i++) {            double gg1=jiao[i];            double gg2=jiao[i+1];            for(int j=1;j<=p*2+2;j++) {                if(edge[j].h!=0&&edge[j].c1<=gg1&&edge[j].c2>=gg2) {                    double ss;                    if(gg1==0.0) {                        ss=edge[j].h*tan(gg2/pp)*edge[j].h/2.0;                    }                    if(gg2==90.0) {                        ss=edge[j].h/tan(gg1/pp)*edge[j].h/2.0;                    }                    if(gg1!=0.0&&gg2!=90.0) {                        if(edge[j].fa==0) ss=fabs(edge[j].h/tan(gg2/pp)-edge[j].h/tan(gg1/pp))*edge[j].h/2.0;                        else ss=fabs(edge[j].h*tan(gg2/pp)-edge[j].h*tan(gg1/pp))*edge[j].h/2.0;                    }                    if(ss<vmax[i]) {                        vmax[i]=ss;                        vis[i]=j;                    }                }            }        }        ans4=0;        for(int i=1;i<nn;i++) {            ans4+=vmax[i];        }        if(sa==0) ans4=0;        printf("%.6f %.6f\n",ans1,ans2);        printf("%.6f %.6f\n",ans3,ans4);    }    return 0;}

1 0