2019CCSU11月校赛 B,G题解 B G

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 }