掉精求调
  • 板块学术版
  • 楼主mlvx
  • 当前回复7
  • 已保存回复7
  • 发布时间2024/12/17 14:03
  • 上次更新2024/12/17 19:30:26
查看原帖
掉精求调
1248522
mlvx楼主2024/12/17 14:03

rt

#include<bits/stdc++.h>
using namespace std;
#define db long double
const db eps=1e-9,pi=acos(-1);
pair<db,db>ercifangcheng(db a,db b,db c){return{(-b+sqrt(b*b-4*a*c))/2/a,(-b-sqrt(b*b-4*a*c))/2/a};}
struct Point{db x,y;}A,B;
bool operator==(Point a,Point b){return abs(a.x-b.x)<=eps&&abs(a.y-b.y)<=eps;}
bool operator!=(Point a,Point b){return abs(a.x-b.x)>eps||abs(a.y-b.y)>eps;}
bool operator<(Point a,Point b){return abs(a.x-b.x)<=eps?a.y<b.y:a.x<b.x;}
bool IsNumber(Point A){return-1e18<A.x&&A.x<1e18&&-1e18<A.y&&A.y<1e18;}
struct Vector{Point s,e;};
db cross(Vector a,Vector b){return(a.s.x-a.e.x)*(b.s.y-b.e.y)-(a.s.y-a.e.y)*(b.s.x-b.e.x);}
db dis(Point a,Point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
db sqdis(Point a,Point b){return(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
db len(Point a,Point b,Point c){return cross({a,b},{a,c})/dis(a,b);}
db qingxiejiao(Point a,Point b){return atan((a.y-b.y)/(a.x-b.x));}
bool OnOneLine(Point a,Point b,Point c){return abs(cross({a,b},{a,c}))<=eps;}
bool OnCircle(Point O,db r,Point P){return abs(sqdis(O,P)-r*r)<=eps;}
bool InCircle(Point O,db r,Point P){return sqdis(O,P)<r*r;}
bool OutCircle(Point O,db r,Point P){return sqdis(O,P)>r*r;}
Point zhongdian(Point A,Point B){return{(A.x+B.x)/2,(A.y+B.y)/2};}
Point zhixianjiaodian(Point A,Point B,Point C,Point D){
	db a1=A.y-B.y,b1=B.x-A.x,c1=A.x*(A.y-B.y)-A.y*(A.x-B.x),a2=D.y-C.y,b2=C.x-D.x,c2=D.x*(D.y-C.y)-D.y*(D.x-C.x);
	return{(c1*b2-c2*b1)/(a1*b2-a2*b1),(a1*c2-a2*c1)/(a1*b2-a2*b1)};
}Point chuizu(Point A,Point B,Point P){
    db k=sqrt(sqdis(A,P)-len(A,B,P)*len(A,B,P))/dis(A,B);
    return{A.x+(B.x-A.x)*k,A.y+(B.y-A.y)*k};
}Point chuixian(Point A,Point B,Point P){
    if(OnOneLine(A,B,P))return P==A?(Point){P.x+B.y-P.y,P.y-B.x+P.x}:(Point){P.x+A.y-P.y,P.y-A.x+P.x};
    else return chuizu(A,B,P);
}Point waixin(Point A,Point B,Point C){
    Point midAB=zhongdian(A,B),midBC=zhongdian(B,C);
    return zhixianjiaodian(midAB,chuixian(A,B,midAB),midBC,chuixian(B,C,midBC));
}Point neixin(Point A,Point B,Point C){
    db k1=1/dis(A,B),k2=1/dis(B,C),k3=1/dis(A,C);
    Point P1={A.x+k1*(B.x-A.x),A.y+k1*(B.y-A.y)},P2={A.x+k3*(C.x-A.x),A.y+k3*(C.y-A.y)},midP=zhongdian(P1,P2),Q1={B.x+k2*(C.x-B.x),B.y+k2*(C.y-B.y)},Q2={B.x+k1*(A.x-B.x),B.y+k1*(A.y-B.y)},midQ=zhongdian(Q1,Q2);
    return zhixianjiaodian(midP,chuixian(P1,P2,midP),midQ,chuixian(Q1,Q2,midQ));
}pair<Point,Point>yuanxianjiaodian(Point O,db r,Point P,Point Q){
    db a1=-2*O.x,b1=-2*O.y,c1=r*r-O.x*O.x-O.y*O.y,A=Q.y-P.y,B=P.x-Q.x,C=P.x*Q.y-P.y*Q.x;
    if(abs(A)<=eps){
        db y=C/B;pair<db,db>x=ercifangcheng(1,a1,y*y+b1*y-c1);
        return{{x.first,y},{x.second,y}};
    }else{
        db u=1+B/A*B/A,v=b1-2*B/A*C/A-a1/A*B,w=C/A*C/A+a1/A*C-c1;
        pair<db,db>y=ercifangcheng(u,v,w),x={(C-B*y.first)/A,(C-B*y.second)/A};
        return{{x.first,y.first},{x.second,y.second}};
    }
}pair<Point,Point>yuanjiaodian(Point O1,db r1,Point O2,db r2){
    db a1=-2*O1.x,b1=-2*O1.y,c1=r1*r1-O1.x*O1.x-O1.y*O1.y,a2=-2*O2.x,b2=-2*O2.y,c2=r2*r2-O2.x*O2.x-O2.y*O2.y,A=a1-a2,B=b1-b2,C=c1-c2;
    if(abs(A)<=eps){
        db y=C/B;pair<db,db>x=ercifangcheng(1,a1,y*y+b1*y-c1);
        return{{x.first,y},{x.second,y}};
    }else{
        db u=1+B/A*B/A,v=b1-2*B/A*C/A-a1/A*B,w=C/A*C/A+a1/A*C-c1;
        pair<db,db>y=ercifangcheng(u,v,w),x={(C-B*y.first)/A,(C-B*y.second)/A};
        return{{x.first,y.first},{x.second,y.second}};
    }
}pair<pair<Point,Point>,pair<Point,Point>>pingyi(Point A,Point B,db l){
    db k=l/dis(A,B),y=B.y-A.y,x=B.x-A.x;
    return{{{A.x+k*y,A.y-k*x},{B.x+k*y,B.y-k*x}},{{A.x-k*y,A.y+k*x},{B.x-k*y,B.y+k*x}}};
}
char s[50];
int main(){
    while(~scanf("%s",s)){
        int L=strlen(s);
        if(L==19){
            db x1,y1,x2,y2,x3,y3;cin>>x1>>y1>>x2>>y2>>x3>>y3;
            Point ans=waixin({x1,y1},{x2,y2},{x3,y3});db d=dis(ans,{x1,y1});
            printf("(%.6Lf,%.6Lf,%.6Lf)\n",ans.x,ans.y,d);
        }if(L==15){
            db x1,y1,x2,y2,x3,y3;cin>>x1>>y1>>x2>>y2>>x3>>y3;
            Point ans=neixin({x1,y1},{x2,y2},{x3,y3});db d=len({x1,y1},{x2,y2},ans);
            printf("(%.6Lf,%.6Lf,%.6Lf)\n",ans.x,ans.y,d);
        }if(L==23){
            db xc,yc,r,xp,yp;cin>>xc>>yc>>r>>xp>>yp;
            if(InCircle({xc,yc},r,{xp,yp}))puts("[]");
            if(OnCircle({xc,yc},r,{xp,yp})){
                db th=qingxiejiao({xp,yp},chuixian({xp,yp},{xc,yc},{xp,yp}));if(th<0)th+=180;
                printf("[%.6Lf]\n",th);
            }if(OutCircle({xc,yc},r,{xp,yp})){
                pair<Point,Point>ans=yuanjiaodian({xc,yc},r,zhongdian({xp,yp},{xc,yc}),dis({xp,yp},{xc,yc})/2);
                db th1=qingxiejiao(ans.first,{xp,yp})/pi*180,th2=qingxiejiao(ans.second,{xp,yp})/pi*180;
                if(th1<0)th1+=180;if(th2<0)th2+=180;if(th1>th2)swap(th1,th2);
                printf("[%.6Lf,%.6Lf]\n",th1,th2);
            }
        }if(L==46){
            db xp,yp,x1,y1,x2,y2,r;cin>>xp>>yp>>x1>>y1>>x2>>y2>>r;
            pair<pair<Point,Point>,pair<Point,Point>>line=pingyi({x1,y1},{x2,y2},r);
            pair<Point,Point>ans1=yuanxianjiaodian({xp,yp},r,line.first.first,line.first.second),ans2=yuanxianjiaodian({xp,yp},r,line.second.first,line.second.second);
            vector<Point>ans;int use[4]={1,1,1,1};
            if(IsNumber(ans1.first))ans.push_back(ans1.first);if(IsNumber(ans1.second))ans.push_back(ans1.second);if(IsNumber(ans2.first))ans.push_back(ans2.first);if(IsNumber(ans2.second))ans.push_back(ans2.second);
            sort(ans.begin(),ans.end()),putchar('[');
            for(int i=0;i<(int)ans.size()-1;i++)if(ans[i]==ans[i+1])use[i]=0;
            for(int i=0;i<ans.size();i++)if(use[i]){
                printf("(%.12Lf,%.12Lf)",ans[i].x,ans[i].y);
                if(i!=ans.size()-1)printf(",");
            }puts("]");
        }
    }
	return 0;
}

86~98行(UVA12304第4问),跑

CircleThroughAPointAndTangentToALineWithRadius 100 200 75 190 185 65 100
CircleThroughAPointAndTangentToALineWithRadius 75 190 75 190 185 65 100
CircleThroughAPointAndTangentToALineWithRadius 100 300 100 100 200 100 100
CircleThroughAPointAndTangentToALineWithRadius 100 300 100 100 200 100 99

掉精了。

2024/12/17 14:03
加载中...