题意:
给你三个点x,y,z之间的距离,三个点一定可以组成三角形,要你输出三个点,且每个点的x坐标范围在0~w之间,每个点的y坐标范围在0~h之间,
题目链接:
https://ac.nowcoder.com/acm/contest/885/I
题解:
来自官方题解的两个结论:
- 1. 若一个三角形能摆在一个矩形里,总是能经过平移使得三角形至少有一个顶点和矩形的顶点重叠,且三角形的顶点仍在矩形里
- 2. 重叠了三角形的某个顶点和矩形的某个顶点后,我们可以把该重叠的点当旋转轴,旋转三角形,使得三角形有另一个点恰好在矩形的某个边上
因此我们需要每局每个点作为原点的情况,且两条边不同的倾向,于是就有六种情况
用余弦定理求出三个点的坐标
输入保证有解,于是我们只需要判断第三个点在不在要求的范围内
y点不需要判断,y点肯定在矩形范围内,如果不在那么就说明x点与y点的距离超出了矩形的对角线,那么无解,所以因为输入有解,所以我们只需要判断z点
具体操作看代码注释
AC_code:
#include<bits/stdc++.h>
#define esp 1e-8
using namespace std;
struct node {
double x, y;
} point[3];
double w, h;
int check(double a, double b, double c, int x, int y, int z) {
point[x].x = 0.0; //点x定在原点
point[x].y = 0.0;
//点y定在贴近x轴的一侧
if(a <= w) {
point[y].x = a;
point[y].y = 0.0;
} else {
point[y].x = w;
point[y].y = sqrt(a*a - w*w);
}
double jc = acos((a*a + b*b - c*c)/(2*a*b)); //通过余弦公式算出长度为a和长度为b的边的夹角
jc += atan(point[y].y / point[y].x);
//算出长度为a的边与x轴的夹角与上一个结果加起来
// 得出长度为b的边与x轴的夹角
//已知夹角便可算出第三个点的位置
point[z].x = cos(jc) * b;
point[z].y = sin(jc) * b;
//判断 y点和x点在不在 w和h的范围内
if(point[z].x >= 0-esp && point[z].x <= w+esp && point[z].y >= 0-esp && point[z].y <= h+esp) {
printf("%.12f %.12f %.12f %.12f %.12f %.12f\n",
point[0].x, point[0].y,
point[1].x, point[1].y,
point[2].x, point[2].y);
return 1;
} else {
return 0;
}
}
int main() {
int t;
double a, b, c;
scanf("%d", &t);
while(t--) {
scanf("%lf %lf %lf %lf %lf", &w, &h, &a, &b, &c);
if(check(a,b,c,0,1,2)) continue;
if(check(a,c,b,1,0,2)) continue;
if(check(b,a,c,0,2,1)) continue;
if(check(c,a,b,1,2,0)) continue;
if(check(b,c,a,2,0,1)) continue;
if(check(c,b,a,2,1,0)) continue;
}
}