18、19点WA了。
不旋转点、坐标轴。
只将每个点沿 a 的方向收缩到原来的 1/p ,跑一遍最小圆覆盖。
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstdlib>
using namespace std;
const int nn=50002;
const double PAI=3.141592653589793238462643383279502884197;
int n,ra,p;
double ansx,ansy,r;
struct Node{ //点
double x,y;
}a[nn];
struct Line{ //直线
double A,B,C;
};
Line Diax(Node,double,double);
Node Jiad(Line,Line);
double Diss(Node);
Node Zngd(Node,Node);
Node Sand(Node,Node,Node);
Line Liad(Node,Node);
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
scanf("%d%d",&ra,&p);//这里用ra代替题目中的a
Line fxa,fxb;//直线fxa是ra的方向 直线fxb垂直fxa于原点
fxa.A=-sin(ra*PAI/180);
fxa.B=cos(ra*PAI/180);
fxa.C=fxb.C=0;
fxb.A=fxa.B,fxb.B=-fxa.A;
for(int i=1;i<=n;i++)
{
Line soz=Diax(a[i],fxa.A,fxa.B);//soz是过点a[i]平行于fxa的直线
Node jid=Jiad(soz,fxb);//jid是soz与fxb的交点
a[i].x=(a[i].x-jid.x)/p+jid.x;
a[i].y=(a[i].y-jid.y)/p+jid.y;
//得到新的a[i]坐标
}
//以下均为最小圆覆盖的部分
for(int i=1;i<=n;i++)
{
swap(a[i],a[rand()%n+1]);
}
for(int i=1;i<=n;i++)
{
if(Diss(a[i])>r)
{
ansx=a[i].x;
ansy=a[i].y;
r=0;
for(int j=1;j<i;j++)
{
if(Diss(a[j])>r)
{
Node yxi=Zngd(a[i],a[j]);
ansx=yxi.x;
ansy=yxi.y;
r=Diss(a[j]);
for(int k=1;k<j;k++)
{
if(Diss(a[k])>r)
{
Node yux=Sand(a[i],a[j],a[k]);
ansx=yux.x;
ansy=yux.y;
r=Diss(a[k]);
}
}
}
}
}
}
printf("%.3lf",r);
return 0;
}
Line Diax(Node t,double A,double B) //将点斜式转化为一般式
{
Line res;
res.A=A;
res.B=B;
res.C=-A*t.x-B*t.y;
return res;
}
Node Jiad(Line l1,Line l2) //求两条直线交点坐标
{
Node res;
if(l1.A==0) swap(l1,l2);
res.y=-(l2.A*l1.C-l1.A*l2.C)/(l2.A*l1.B-l1.A*l2.B);
res.x=-(l1.B*res.y+l1.C)/l1.A;
return res;
}
double Diss(Node t) //求点t与原点的距离
{
return sqrt((t.x-ansx)*(t.x-ansx)+(t.y-ansy)*(t.y-ansy));
}
Node Zngd(Node t1,Node t2) //求两个点的中点坐标
{
Node res;
res.x=(t1.x+t2.x)/2;
res.y=(t1.y+t2.y)/2;
return res;
}
Node Sand(Node t1,Node t2,Node t3) //求三点定圆的圆心
{
Line l12=Liad(t1,t2);
Line l23=Liad(t2,t3);
if(l12.A*l23.B==l12.B*l23.A) //如果三点共线
{
if(t1.x!=t2.x)
{
if(t1.x>t2.x) swap(t1,t2);
if(t2.x>t3.x) swap(t2,t3);
if(t1.x>t2.x) swap(t1,t2);
}
else
{
if(t1.y>t2.y) swap(t1,t2);
if(t2.y>t3.y) swap(t2,t3);
if(t1.y>t2.y) swap(t1,t2);
}
return Zngd(t1,t3);
}
Node z12=Zngd(t1,t2);
Line g1=Diax(z12,l12.B,l12.A);
Node z23=Zngd(t2,t3);
Line g2=Diax(z23,l23.B,l23.A);
return Jiad(g1,g2);
}
Line Liad(Node t1,Node t2) //将两点式转化为一般式
{
Line res;
res.A=t2.y-t1.y;
res.B=t1.x-t2.x;
res.C=-res.A*t1.x-res.B*t1.y;
return res;
}