题意:

给你三个点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;
	}


}