最小覆盖圆模板+例题两题

🎈最小覆盖圆模板

#include<bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define ll long long
#define mod 1000000007
#define inf 0x7f
#define eps 1e-7
#define LD double
#define ull unsigned long long
#define y1 yy1
#define nxt(i) ((i+1)%s.size())
#define pb push_back
using namespace std;
int sgn(LD x){
    return fabs(x)<eps ? 0:(x>0 ? 1:-1);
}
struct P;
struct L;
typedef P V;
struct P{
    LD x,y;
    explicit P(LD x=0,LD y=0):x(x),y(y){}
    explicit P(const L& l);
};
struct L{
    P s,t;
    L(){}
    L(P s,P t):s(s),t(t){}
};
struct C{
    P p;LD r;
    C(LD x=0,LD y=0,LD r=0):p(x,y),r(r){}
    C(P p,LD r):p(p),r(r){}
};
P operator +(const P& a, const P& b) { return P(a.x + b.x, a.y + b.y); }
P operator -(const P& a, const P& b) { return P(a.x - b.x, a.y - b.y); }
P operator *(const P& a, LD k) { return P(a.x * k, a.y * k); }
P operator /(const P& a, LD k) { return P(a.x / k, a.y / k); }
bool operator <(const P& a,const P& b){return sgn(a.x - b.x)<0 || (sgn(a.x - b.x)==0 && sgn(a.y - b.y)<0);}
bool operator ==(const P& a,const P& b){ return !sgn(a.x - b.x) && !sgn(a.y - b.y);}
P::P(const L& l){ *this = l.t - l.s; }
ostream &operator <<(ostream &os,const P &p){return (os << "(" << p.x << "," << p.y << ")");}
istream &operator >>(istream& is, P& p){return (is>>p.x>>p.y);}
LD dist(const P& p) { return sqrt(p.x * p.x + p.y * p.y);}
LD dot(const V& a, const V& b) { return a.x * b.x + a.y * b.y;}
LD det(const V& a, const V& b) { return a.x * b.y - a.y * b.x;}
LD cross(const P& s, const P& t, const P& o = P()) { return det(s - o, t - o);}
P ccc(P a,P b){return (a+b)/2;}
bool pic(const P& p,const C& c){
    return sgn(dist(p-c.p)-c.r)<=0;
}
P RotateCW90(const P& p){
    return P(p.y,-p.x);
}
struct LV{
    P p,v;LD ang;
    LV(){}
    LV(P s,P t):p(s),v(t-s){ang=atan2(v.y,v.x);}
};
P l_in(const LV &a,const LV& b){
    P u=a.p-b.p;LD t=cross(b.v,u)/cross(a.v,b.v);
    return a.p+a.v*t;
}
P ccp(P a,P b,P c){
    b=(a+b)/2;
    c=(a+c)/2;
    return l_in({b,b+RotateCW90(a-b)},{c,c+RotateCW90(a-c)});
}
C mincc(const vector<P>& in){
    vector<P>a(in.begin(),in.end());
    random_shuffle(a.begin(),a.end());
    P c=a[0];LD r=0;int n=a.size();
    for(int i=1;i<n;i++){
        if(!pic(a[i],{c,r})){
                c=a[i];r=0;
            for(int j=0;j<i;j++){
                if(!pic(a[j],{c,r})){
                    c=ccc(a[i],a[j]);
                    r=dist(a[j]-c);
                    for(int k=0;k<j;k++){
                        if(!pic(a[k],{c,r})){
                            c=ccp(a[i],a[j],a[k]);
                            r=dist(a[k]-c);
                        }
                    }
                }
            }
        }
    }
    return {c,r};
}

🎈hdu4720

题意

给定四个点,需判断第四个点是否在前三个点的最小覆盖圆上

AC代码

#include<bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define ll long long
#define mod 1000000007
#define inf 0x7f
#define eps 1e-7
#define LD double
#define ull unsigned long long
#define y1 yy1
#define nxt(i) ((i+1)%s.size())
#define pb push_back
using namespace std;
int sgn(LD x){
    return fabs(x)<eps ? 0:(x>0 ? 1:-1);
}
struct P;
struct L;
typedef P V;
struct P{
    LD x,y;
    explicit P(LD x=0,LD y=0):x(x),y(y){}
    explicit P(const L& l);
};
struct L{
    P s,t;
    L(){}
    L(P s,P t):s(s),t(t){}
};
struct C{
    P p;LD r;
    C(LD x=0,LD y=0,LD r=0):p(x,y),r(r){}
    C(P p,LD r):p(p),r(r){}
};
P operator +(const P& a, const P& b) { return P(a.x + b.x, a.y + b.y); }
P operator -(const P& a, const P& b) { return P(a.x - b.x, a.y - b.y); }
P operator *(const P& a, LD k) { return P(a.x * k, a.y * k); }
P operator /(const P& a, LD k) { return P(a.x / k, a.y / k); }
bool operator <(const P& a,const P& b){return sgn(a.x - b.x)<0 || (sgn(a.x - b.x)==0 && sgn(a.y - b.y)<0);}
bool operator ==(const P& a,const P& b){ return !sgn(a.x - b.x) && !sgn(a.y - b.y);}
P::P(const L& l){ *this = l.t - l.s; }
ostream &operator <<(ostream &os,const P &p){return (os << "(" << p.x << "," << p.y << ")");}
istream &operator >>(istream& is, P& p){return (is>>p.x>>p.y);}
LD dist(const P& p) { return sqrt(p.x * p.x + p.y * p.y);}
LD dot(const V& a, const V& b) { return a.x * b.x + a.y * b.y;}
LD det(const V& a, const V& b) { return a.x * b.y - a.y * b.x;}
LD cross(const P& s, const P& t, const P& o = P()) { return det(s - o, t - o);}
P ccc(P a,P b){return (a+b)/2;}
bool pic(const P& p,const C& c){
    return sgn(dist(p-c.p)-c.r)<=0;
}
P RotateCW90(const P& p){
    return P(p.y,-p.x);
}
struct LV{
    P p,v;LD ang;
    LV(){}
    LV(P s,P t):p(s),v(t-s){ang=atan2(v.y,v.x);}
};
P l_in(const LV &a,const LV& b){
    P u=a.p-b.p;LD t=cross(b.v,u)/cross(a.v,b.v);
    return a.p+a.v*t;
}
P ccp(P a,P b,P c){
    b=(a+b)/2;
    c=(a+c)/2;
    return l_in({b,b+RotateCW90(a-b)},{c,c+RotateCW90(a-c)});
}
C mincc(const vector<P>& in){
    vector<P>a(in.begin(),in.end());
    random_shuffle(a.begin(),a.end());
    P c=a[0];LD r=0;int n=a.size();
    for(int i=1;i<n;i++){
        if(!pic(a[i],{c,r})){
                c=a[i];r=0;
            for(int j=0;j<i;j++){
                if(!pic(a[j],{c,r})){
                    c=ccc(a[i],a[j]);
                    r=dist(a[j]-c);
                    for(int k=0;k<j;k++){
                        if(!pic(a[k],{c,r})){
                            c=ccp(a[i],a[j],a[k]);
                            r=dist(a[k]-c);
                        }
                    }
                }
            }
        }
    }
    return {c,r};
}
int main(){
    srand(time(0));
    int n;scanf("%d",&n);
    int cc=0;
    while(n--){
        vector<P>p1;
        for(int i=0;i<3;i++){
            double x,y;
            scanf("%lf%lf",&x,&y);
            p1.pb(P{x,y});
        }
        LD xx,yy;
        scanf("%lf%lf",&xx,&yy);
        C ans=mincc(p1);
        cc++;
        if(pic(P{xx,yy},ans)){
            printf("Case #%d: Danger\n",cc);
        }
        else{
            printf("Case #%d: Safe\n",cc);
        }
    }
    return 0;
}
/*
*/

🎈 A——Weird Flecks, But OK

题意

钻头只能垂直于其一个面进入立方体一次。立方体的面平行于坐标轴。
鉴于缺陷的(x,y,z)位置,并且将缺陷的大小忽略不计,一次操作中可用于去除缺陷的最小直径的钻头是多少?

思路

xy,yz,xz三种圆求第四个点的最小距离

AC代码

#include<bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define ll long long
#define mod 1000000007
#define inf 0x7f
#define eps 1e-7
#define LD double
#define ull unsigned long long
#define y1 yy1
#define nxt(i) ((i+1)%s.size())
#define pb push_back
using namespace std;
int sgn(LD x){
    return fabs(x)<eps ? 0:(x>0 ? 1:-1);
}
struct P;
struct L;
typedef P V;
struct P{
    LD x,y;
    explicit P(LD x=0,LD y=0):x(x),y(y){}
    explicit P(const L& l);
};
struct L{
    P s,t;
    L(){}
    L(P s,P t):s(s),t(t){}
};
struct C{
    P p;LD r;
    C(LD x=0,LD y=0,LD r=0):p(x,y),r(r){}
    C(P p,LD r):p(p),r(r){}
};
P operator +(const P& a, const P& b) { return P(a.x + b.x, a.y + b.y); }
P operator -(const P& a, const P& b) { return P(a.x - b.x, a.y - b.y); }
P operator *(const P& a, LD k) { return P(a.x * k, a.y * k); }
P operator /(const P& a, LD k) { return P(a.x / k, a.y / k); }
bool operator <(const P& a,const P& b){return sgn(a.x - b.x)<0 || (sgn(a.x - b.x)==0 && sgn(a.y - b.y)<0);}
bool operator ==(const P& a,const P& b){ return !sgn(a.x - b.x) && !sgn(a.y - b.y);}
P::P(const L& l){ *this = l.t - l.s; }
ostream &operator <<(ostream &os,const P &p){return (os << "(" << p.x << "," << p.y << ")");}
istream &operator >>(istream& is, P& p){return (is>>p.x>>p.y);}
LD dist(const P& p) { return sqrt(p.x * p.x + p.y * p.y);}
LD dot(const V& a, const V& b) { return a.x * b.x + a.y * b.y;}
LD det(const V& a, const V& b) { return a.x * b.y - a.y * b.x;}
LD cross(const P& s, const P& t, const P& o = P()) { return det(s - o, t - o);}
P ccc(P a,P b){return (a+b)/2;}
bool pic(const P& p,const C& c){
    return sgn(dist(p-c.p)-c.r)<=0;
}
P RotateCW90(const P& p){
    return P(p.y,-p.x);
}
struct LV{
    P p,v;LD ang;
    LV(){}
    LV(P s,P t):p(s),v(t-s){ang=atan2(v.y,v.x);}
};
P l_in(const LV &a,const LV& b){
    P u=a.p-b.p;LD t=cross(b.v,u)/cross(a.v,b.v);
    return a.p+a.v*t;
}
P ccp(P a,P b,P c){
    b=(a+b)/2;
    c=(a+c)/2;
    return l_in({b,b+RotateCW90(a-b)},{c,c+RotateCW90(a-c)});
}
LD mincc(const vector<P>& in){
    vector<P>a(in.begin(),in.end());
    random_shuffle(a.begin(),a.end());
    P c=a[0];LD r=0;int n=a.size();
    for(int i=1;i<n;i++){
        if(!pic(a[i],{c,r})){
                c=a[i];r=0;
            for(int j=0;j<i;j++){
                if(!pic(a[j],{c,r})){
                    c=ccc(a[i],a[j]);
                    r=dist(a[j]-c);
                    for(int k=0;k<j;k++){
                        if(!pic(a[k],{c,r})){
                            c=ccp(a[i],a[j],a[k]);
                            r=dist(a[k]-c);
                        }
                    }
                }
            }
        }
    }
    return r;
}
vector<P>p1,p2,p3;
int main(){
    srand(time(0));
    int n;scanf("%d",&n);
    for(int i=0;i<n;i++){
        double x,y,z;
        scanf("%lf%lf%lf",&x,&y,&z);
        p1.pb(P{x,y});
        p2.pb(P{x,z});
        p3.pb(P{z,y});
    }
    double ans=min(mincc(p1),min(mincc(p2),mincc(p3)));
    printf("%f\n",ans*2);
    return 0;
}
posted @ 2021-04-15 21:25  ouluy  阅读(102)  评论(0编辑  收藏  举报