zoukankan      html  css  js  c++  java
  • [bzoj2517]矩形覆盖

    Description

    给定一个$l; imes;w$的矩形,和$n$个圆,求最小的$k$使得每个圆的半径$; imes;k$后,能覆盖整个矩形.

    Input

    第一行一个整数$T$,表示数据组数.

    以下$T$组数据,每组数据第一行三个整数$N,L,W$,表示圆个数和矩形大小.

    接下来$N$行,每行三个正整数$x[i],y[i],R[i]$表示一个圆心的坐标和原始半径.

    Output

    对于每组数据,输出一个实数$K$,保留$3$位小数.

    Sample Input

    1
    1 2 2
    1 1 1

    Sample Output

    1.414

    HINT

    $t;leq;10,n;leq;50,x[i],y[i],R[i];leq;1000$

    Solution

    二分$k$,分治矩形判断当前$k$是否可行:

    $1.$如果当前矩形的四个顶点在同一圆内,可行;

    $2.$如果当前矩形有一个顶点不在圆内,不可行;

    $3.$如果当前矩形的四个顶点不在同一圆内,分成$4$部分继续判断.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 55
    #define K 1e-7
    #define eps 1e-13
    using namespace std;
    int n,t;
    double a[N],x[N],y[N],r[N],l,w,lef,rig,mid;
    inline double sqr(double x){
        return x*x;
    } 
    inline bool in(int i,double k,double n,double m){
        double d=sqr(x[i]-n)+sqr(y[i]-m);
        return d<=sqr(r[i])+eps;
    }
    inline bool chk(double k,double n1,double n2,double m1,double m2){
        bool f1=0,f2=0,f3=0,f4=0;
        if(fabs(n1-n2)<eps&&fabs(m1-m2)<eps) return true;
        for(int i=1,l1,l2,l3,l4;i<=n;++i){
            l1=in(i,k,n1,m1);l2=in(i,k,n1,m2);
            l3=in(i,k,n2,m1);l4=in(i,k,n2,m2);
            if(l1&&l2&&l3&&l4) return true;
            f1|=l1;f2|=l2;f3|=l3;f4|=l4;
        }
        if(!f1||!f2||!f3||!f4) return false;
        double mm=(m1+m2)*0.5,nn=(n1+n2)*0.5;
        return chk(k,n1,nn,m1,mm)&&chk(k,n1,nn,mm,m2)
          &&chk(k,nn,n2,m1,mm)&&chk(k,nn,n2,mm,m2);
    }
    inline void Aireen(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%lf%lf",&n,&l,&w);
            for(int i=1;i<=n;++i)
                scanf("%lf%lf%lf",&x[i],&y[i],&a[i]);
            lef=0.0;rig=l+w;
            while(lef+K<rig){
                mid=(lef+rig)*0.5;
                for(int i=1;i<=n;++i)
                    r[i]=a[i]*mid;
                if(chk(mid,0.0,l,0.0,w)) rig=mid;
                else lef=mid+K;
            }
            printf("%.3lf
    ",lef);
        }
    }
    int main(){
        freopen("cover.in","r",stdin);
        freopen("cover.out","w",stdout);
        Aireen();
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    [codevs 1227] 方格取数 2
    记冬令营
    Codeforces Round 558(Div 2)题解
    Educational Round 64 题解
    [GXOI/GZOI2019]与或和(位运算,单调栈)
    LOJ6053 简单的函数(min_25筛)
    LOJ6235 区间素数个数(min_25筛)
    min_25筛学习笔记
    CF1142C U2(计算几何,凸包)
    关于一些没做出来的SBCF题
  • 原文地址:https://www.cnblogs.com/AireenYe/p/6230646.html
Copyright © 2011-2022 走看看