2019牛客暑期多校训练营(第五场) three points 1 计算几何

题目链接:https://ac.nowcoder.com/acm/contest/885/I

 

题意:

        给你五个值w,h,a,b,c.现在要你在二维平面坐标上找三个点X,Y,Z。要求,X和Y之间的距离为a,X和Z之间的距离为b,Y和Z之间的距离为c。所有三个坐标的横坐标不能超过w,纵坐标不能超过h。给出的数据保证一定有解,要你求出这三个点的坐标。(坐标可以为实数)

做法:

       赛中的时候想到了一个做法,但是不知道为什么一直错,明明也是很合理的说。(晚点再表达,如果有问题的被看到的希望指出。先讲问到的应该是正确的做法)

       因为只要这个三角形是合法的,那么总是可以把它进行平移,使得它的一个点在某一个顶点,另一个点在某一条边上。所以我们枚举每个点在原点的位置,选一个点与矩形的左边或者上面相交(看这个边的长度就做决定),最后再用余弦定理的方法找到第三个点。然后把w和h换一下再试一次(最后换回来就好了)。然后找到一个合理的位置之后就不找了。就好了

        原来的做法是,选定一个点在源点(枚举),然后用这个点和另外两个边的长度找到和矩形的交点。一共是四个点,x1,x2,y1,y2,然后找到x1和x2中和y1、y2距离最远的点,然后用这个点和源点位置的点做圆,判断两圆的交点。

 


#include
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
const double eps=1e-7;
const double pi=acos(-1.0);
struct Point{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
int dcmp(double x){
    if (fabs(x) < eps)return 0;
    else if (x > 0)return 1;
    return -1;
}
Vector operator + (Vector a, Vector b){
    return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (Vector a, Vector b){
    return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (Vector a, double p){
    return Vector(a.x*p, a.y*p);
}
Vector operator / (Vector a, double p){
    return Vector(a.x / p, a.y / p);
}
bool operator == (const Point &a, const Point &b){
  return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
Vector Rotate(Vector a, double rad){//逆时针旋转
    return Vector(a.x*cos(rad) - a.y*sin(rad), a.x*sin(rad) + a.y*cos(rad));
}
double a,b,c,w,h;
int ck(Point x){
    return dcmp(x.x)>=0&&dcmp(x.x-w)<=0&&dcmp(x.y)>=0&&dcmp(x.y-h)<=0;
}
bool yes;

void deal(Point &X,double a,Point &Y,double b,Point &Z,double c,double w,double h){
    if(yes==true) return ;
    //printf("val = %.5f  ang = %.5f\n",(a*a+b*b-c*c)/(2*a*b),acos((a*a+b*b-c*c)/(2*a*b)));
    double ang=acos((a*a+b*b-c*c)/(2*a*b));
    X.x=0,X.y=0;
    if(dcmp(h-a)>0){
        Y.x=0,Y.y=a;
    }
    else{
        Y.y=h,Y.x=sqrt(a*a-h*h);
    }
    Z=Rotate(Y/a*b,-ang);
    if(ck(Z)) yes=true;
}
int main(){
    int T; scanf("%d",&T);
    while(T--){
        scanf("%lf%lf%lf%lf%lf",&w,&h,&a,&b,&c);
        Point X,Y,Z;
        yes=false;
        int flag=0;
        deal(X,a,Y,b,Z,c,w,h);
        deal(X,b,Z,a,Y,c,w,h);
        deal(Y,a,X,c,Z,b,w,h);
        deal(Y,c,Z,a,X,b,w,h);
        deal(Z,b,X,c,Y,a,w,h);
        deal(Z,c,Y,b,X,a,w,h);
        if(yes==false) flag=1;
        deal(X,a,Y,b,Z,c,h,w);
        deal(X,b,Z,a,Y,c,h,w);
        deal(Y,a,X,c,Z,b,h,w);
        deal(Y,c,Z,a,X,b,h,w);
        deal(Z,b,X,c,Y,a,h,w);
        deal(Z,c,Y,b,X,a,h,w);
        if(!flag) printf("%.12f %.12f %.12f %.12f %.12f %.12f\n",X.x,X.y,Y.x,Y.y,Z.x,Z.y);
        else printf("%.12f %.12f %.12f %.12f %.12f %.12f\n",X.y,X.x,Y.y,Y.x,Z.y,Z.x);
    }
    return  0;
}

 

你可能感兴趣的:(计算几何)