2019牛客暑期多校训练营(第五场)I题题解
https://ac.nowcoder.com/acm/contest/885/I
题意
给定一个矩形区域,在里面构造三个点使得其之间的距离等于给定的值
题解
如图所示,先取(0,0)作为第一点,然后分两种情况:在x轴上或矩形右边界找第二个点,最后用余弦定理和角度关系求出第三点。
注意:因为可能会出现超过w,h边界的情况,我们可以枚举三个点对应放哪个位置来保证答案合法。
代码很好写:
1 #define bug(x) cout<<#x<<" is "<<x<<endl 2 #define IO std::ios::sync_with_stdio(0) 3 #include <bits/stdc++.h> 4 using namespace std; 5 const double eps=1e-10; 6 double w,h; 7 int T; 8 struct node{ 9 double x,y; 10 }p[10]; 11 int dcmp(double x){ 12 if(fabs(x)<eps)return 0; 13 return x<0?-1:1; 14 } 15 int judge(){ 16 for(int i=1;i<=3;i++){ 17 if(dcmp(p[i].x)<0||dcmp(p[i].x-w)>0||dcmp(p[i].y)<0||dcmp(p[i].y-h)>0)return 0; 18 } 19 return 1; 20 } 21 int check(double a,double b,double c,int X,int Y,int Z){ 22 p[X].x=p[X].y=0; 23 if(a<=w){ 24 p[Y].x=a; 25 p[Y].y=0; 26 double g=acos((a*a+b*b-c*c)/(2*a*b)); 27 p[Z].x=b*cos(g); 28 p[Z].y=b*sin(g); 29 } 30 else{ 31 p[Y].x=w; 32 double h1=sqrt(a*a-w*w); 33 p[Y].y=h1; 34 double g1=acos(w/a); 35 double g2=acos((a*a+b*b-c*c)/(2*a*b)); 36 g1+=g2; 37 p[Z].x=b*cos(g1); 38 p[Z].y=b*sin(g1); 39 } 40 if(judge()){ 41 for(int i=1;i<=3;i++){ 42 printf("%.10lf %.10lf%c",p[i].x,p[i].y,i==3?'\n':' '); 43 } 44 return 1; 45 } 46 return 0; 47 } 48 int main(){ 49 scanf("%d",&T); 50 while(T--){ 51 double a,b,c; 52 cin>>w>>h>>a>>b>>c; 53 if(check(a,b,c,1,2,3))continue; 54 if(check(a,c,b,2,1,3))continue; 55 if(check(b,a,c,1,3,2))continue; 56 if(check(b,c,a,3,1,2))continue; 57 if(check(c,a,b,2,3,1))continue; 58 if(check(c,b,a,3,2,1))continue; 59 } 60 }