B
https://ac.nowcoder.com/acm/contest/2891/B
题解
简单贪心题。
对数组排序,每三个组成一组求出差值之后取最大值就是答案。
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int n; 5 int a[300005]; 6 7 int main(){ 8 scanf("%d",&n); 9 for(int i=1;i<=n*3;i++){ 10 scanf("%d",&a[i]); 11 } 12 sort(a+1,a+1+n*3); 13 int ans=0; 14 for(int i=1;i<=n*3;i+=3){ 15 ans=max(ans,a[i+2]-a[i]); 16 } 17 printf("%d ",ans); 18 }
G
https://ac.nowcoder.com/acm/contest/2891/G
题解
入门几何题。
容易看出在两个三角形上找到最近的两个点作为圆的直径最优。
简单分析发现,这个距离实际上就是点到线段的距离,那么我们枚举所有点到线段的距离取最小值就是答案。
求点到线段的距离分两种情况。
1,点到线段端点的距离;
2,点到这条线段的所在的直线的距离。
我们用向量点积符号判断属于哪种情况,如果点积为负是第1种否则为第2种。
计算第2种可以用高中学过的点到直线的距离公式。
但不建议这么做,建议直接学板子,比如学会本辣鸡几何选手 的板子就随便写这题:)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const double Pi=acos(-1); 4 const double eps=1e-10; 5 struct Point{//点 6 double x,y; 7 Point(double x=0,double y=0):x(x),y(y){}; 8 }; 9 typedef Point Vector; 10 Vector operator +(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);} 11 Vector operator -(Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);} 12 Vector operator *(Vector A,double B){return Vector(A.x*B,A.y*B);} 13 Vector operator /(Vector A,double B){return Vector(A.x/B,A.y/B);} 14 int dcmp(double x){ 15 if(fabs(x)<eps)return 0; 16 return x<0?-1:1; 17 } 18 bool operator<(const Point&a,const Point&b){return a.x<b.x||(a.x==b.x&&a.y<b.y);} 19 bool operator == (const Point &a,const Point &b){return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;} 20 void Correct(double &A){ 21 while(dcmp(A)<0)A+=Pi; 22 while(dcmp(A-Pi)>=0)A-=Pi; 23 } 24 double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;} 25 double Length(Vector A){return sqrt(Dot(A,A));} 26 double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;} 27 void readp(Point &A){ 28 scanf("%lf%lf",&A.x,&A.y); 29 } 30 double dis(Point P,Point A,Point B){//点到线段的距离 31 if(A==B)return Length(P-A); 32 Vector v1=B-A,v2=P-A,v3=P-B; 33 if(dcmp(Dot(v1,v2))<0)return Length(v2); 34 else if(dcmp(Dot(v1,v3)>0))return Length(v3); 35 else return fabs(Cross(v1,v2))/Length(v1); 36 } 37 int T; 38 Point p[10],t[10]; 39 int main(){ 40 scanf("%d",&T); 41 while(T--){ 42 for(int i=1;i<=3;i++){ 43 readp(p[i]); 44 } 45 for(int i=1;i<=3;i++){ 46 readp(t[i]); 47 } 48 double ans=1e18; 49 for(int i=1;i<=3;i++){ 50 ans=min(ans,dis(p[i],t[1],t[2])); 51 ans=min(ans,dis(p[i],t[1],t[3])); 52 ans=min(ans,dis(p[i],t[2],t[3])); 53 54 ans=min(ans,dis(t[i],p[1],p[2])); 55 ans=min(ans,dis(t[i],p[1],p[3])); 56 ans=min(ans,dis(t[i],p[2],p[3])); 57 } 58 printf("%.10lf ",ans/2); 59 } 60 }