洛谷P4288||bzoj3564 [SHOI2014]信号增幅仪
可以旋转一下坐标轴使得x轴与长轴方向对齐,然后将所有的横坐标变为自身除以放大倍数,然后就做一个最小圆覆盖
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<cmath> 6 #include<ctime> 7 using namespace std; 8 #define fi first 9 #define se second 10 #define mp make_pair 11 #define pb push_back 12 typedef long long ll; 13 typedef unsigned long long ull; 14 typedef pair<int,int> pii; 15 namespace X 16 { 17 const double pi=acos(-1); 18 const double eps=1e-6; 19 struct Point 20 { 21 double x,y; 22 Point(double x=0,double y=0):x(x),y(y){} 23 }; 24 typedef Point Vec; 25 Vec operator+(const Vec& a,const Vec& b) 26 { 27 return Vec(a.x+b.x,a.y+b.y); 28 } 29 Vec operator-(const Vec& a,const Vec& b) 30 { 31 return Vec(a.x-b.x,a.y-b.y); 32 } 33 Vec operator*(double a,const Vec& b) 34 { 35 return Vec(a*b.x,a*b.y); 36 } 37 Vec operator*(const Vec& a,double b) 38 { 39 return Vec(b*a.x,b*a.y); 40 } 41 Vec operator/(const Vec& a,double b) 42 { 43 return Vec(a.x/b,a.y/b); 44 } 45 int dcmp(double x) 46 //正为1,负为-1,0为0 47 { 48 if(fabs(x)<eps) return 0; 49 return x<0?-1:1; 50 } 51 bool operator==(const Vec& a,const Vec& b) 52 //判向量相等 53 { 54 return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; 55 } 56 double dot(const Vec& a,const Vec& b) 57 //点积 58 { 59 return a.x*b.x+a.y*b.y; 60 } 61 double cross(const Vec& a,const Vec& b) 62 //叉积 63 { 64 return a.x*b.y-a.y*b.x; 65 } 66 double len(const Vec& x) 67 //向量长度 68 { 69 return sqrt(dot(x,x)); 70 } 71 double angle(const Vec& a,const Vec& b) 72 //夹角,0~180° 73 { 74 return acos(dot(a,b)/len(a)/len(b)); 75 } 76 double angle1(const Vec& a,const Vec& b) 77 //夹角,带方向,a到b逆时针为正,顺时针为负,共线为0 78 { 79 return acos(dot(a,b)/len(a)/len(b))*(dcmp(cross(a,b))); 80 } 81 Vec rotate(const Vec& a,double rad) 82 //旋转,正为逆时针,负为顺时针 83 { 84 return Vec(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad)); 85 } 86 Vec normal(const Vec& x) 87 //单位法线,左转90°后除以自身长度 88 { 89 double l=len(x); 90 return Vec(-x.y/l,x.x/l); 91 } 92 Vec normal1(const Vec& x) 93 //法线,不归一化 94 { 95 return Vec(-x.y,x.x); 96 } 97 Point lineline(const Point& p,const Vec& v,const Point& q,const Vec& w) 98 //直线交点,GetLineIntersection 99 { 100 return p+v*cross(w,p-q)/cross(v,w); 101 } 102 double ptline(const Point& p,const Point& a,const Point& b) 103 //point_to_line,点到直线距离,DistanceToLine 104 { 105 Vec v1=b-a,v2=p-a; 106 return fabs(cross(v1,v2)/len(v1)); 107 } 108 double ptseg(const Point& p,const Point& a,const Point& b) 109 //point_to_segment,点到线段距离,DistanceToSegment 110 { 111 if(a==b) return len(p-a); 112 //Vec v1=b-a,v2=a-p,v3=p-b; 113 Vec v1=b-a,v2=p-a,v3=p-b; 114 if(dcmp(dot(v1,v2))<0) return len(v2); 115 else if(dcmp(dot(v1,v3))>0) return len(v3); 116 else return fabs(cross(v1,v2)/len(v1)); 117 } 118 double area2(const Point& a,const Point& b,const Point& c) 119 //叉积对应平行四边形的面积 120 { 121 return cross(b-a,c-a); 122 } 123 double thrarea(const Point& a,const Point& b,const Point& c) 124 //三角形面积,绝对值 125 { 126 return fabs(cross(b-a,c-a)/2); 127 } 128 bool ifpar(const Vec& a,const Vec& b) 129 //ifParallel 130 //是否共线/平行 131 { 132 return dcmp(cross(a,b))==0; 133 } 134 Point pointline(const Point& p,const Point& a,const Vec& v) 135 //点在直线上投影,GetLineProjection 136 { 137 return a+v*(dot(p-a,v)/dot(v,v)); 138 } 139 double sqr(double x){return x*x;} 140 double dis2(const Point &x,const Point &y) 141 { 142 return sqr(x.x-y.x)+sqr(x.y-y.y); 143 } 144 double len2(const Vec &x){return dot(x,x);} 145 }; 146 using namespace X; 147 Point p[1000100]; 148 int n; 149 Point a; 150 double r2; 151 double A,B; 152 void make(const Point &x,const Point &y) 153 { 154 Vec t=(y-x)/2; 155 a=x+t; 156 r2=len2(t); 157 } 158 void make(const Point &x,const Point &y,const Point &z) 159 { 160 Vec t1=(y-x)/2,t2=(z-y)/2; 161 Point x1=x+t1,y1=y+t2; 162 t1=normal1(t1);t2=normal1(t2); 163 a=lineline(x1,t1,y1,t2); 164 r2=dis2(a,x); 165 } 166 bool ok(const Point &x) 167 { 168 return dcmp(dis2(x,a)-r2)<=0; 169 } 170 int main() 171 { 172 int i,j,k; 173 srand(time(0)); 174 scanf("%d",&n); 175 for(i=1;i<=n;i++) 176 scanf("%lf%lf",&p[i].x,&p[i].y); 177 scanf("%lf%lf",&A,&B);A=A/180*pi; 178 for(i=1;i<=n;i++) 179 p[i]=rotate(p[i],-A); 180 for(i=1;i<=n;i++) 181 p[i].x/=B; 182 random_shuffle(p+1,p+n+1); 183 a=p[1];r2=0; 184 for(i=2;i<=n;i++) 185 if(!ok(p[i])) 186 { 187 a=p[i];r2=0; 188 for(j=1;j<i;j++) 189 if(!ok(p[j])) 190 { 191 make(p[i],p[j]); 192 for(k=1;k<j;k++) 193 if(!ok(p[k])) 194 { 195 make(p[i],p[j],p[k]); 196 } 197 } 198 } 199 //uprintf("%.2f %.2f ",a.x,a.y); 200 printf("%.3f\n",sqrt(r2)); 201 return 0; 202 }