问题虫洞:three points 1
黑洞内窥:
t组样例,每组样例输入w, h, a, b, c,五个数字且都不大于50.
意为在坐标系中,0 <= x <= w, 0<=y<=h,求出三个点X, Y, Z, 并且|XY| = a, |XZ| = b, |YZ| = c,
求这三点坐标并依次输出。
思维光年:
一开始不太正确的做法:
找出最长的边c (假设这里是c)靠在x轴上,一端点在(0, 0), 然后求另一端点
如果c>x,则该边向上旋转,直到接触到wh这个矩阵的边,然后设该点为第二个端点。
之后你知道了两个点,三条边,你就可以用余弦定理和勾股定理求出第三个点,
那么问题就是你要放哪一条边更靠近y轴呢?!(或者说是挑哪一条边的端点连接零点(0,0))
相信绝大多数人和我一样放了第二大的边b(设b为第二大的边)
然后,这样的话,~~问题就解决了!! 恭喜你可以wa到死了。。。
其实咋的一想,我们都范了想当然的错误,为什么呢?!
因为有的时候你需要放小边连接零点,而放中边则会导致另一端点超出wh的范围。。。。
(有人反应BZ偷懒不画图,,,,哭唧唧~~~~再也不用word画图了)
(这个图还是比较清秀的,,,,看到了吧,,,,,)
所以,其实我们把小边和中边各跑一遍,应该可以过,(应该可以,没敲过。。)
真正的做法:
所以,不如干脆写成函数,暴力abc的每个排序,符合就输出,(而题目给出总有符合的)否则就继续找。。。
还有就是,用反函数,不要用联立余弦勾股的方程组求解(wa到怀疑人生),即便你可以二分区间找到答案。。。
对了,最后就精度问题出题人也不忘卡你一下,,,所以,,,你也要卡一下至少1e-6的精度范围。
ACcode:
//#include<bits/stdc++.h>
//std::ios::sync_with_stdio(false);
#include <stdio.h>
#include <iostream>
#include<algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <math.h>
#include <vector>
#include <cstring>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef long long ll;
#define MAXN 3005
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
//const ll mod = 9901;
#define mem(a, b) memset(a, b, sizeof(a))
ll mod;
double w, h;
struct node
{
double x, y;
} stu[3];
int solution(double a, double b, double c, int x, int y, int z)
{
stu[x].x = 0.0;
stu[x].y = 0.0;
if(a <= w)
{
stu[y].x = a;
stu[y].y = 0.0;
}
else
{
stu[y].x = w;
stu[y].y = sqrt(a*a - w*w);
}
double d = acos((a*a+b*b-c*c)*1.0/(2*a*b));//这里用反函数求角度
d+=atan(stu[y].y*1.0 / stu[y].x);
stu[z].x = b*cos(d); //知道角度用三角函数直接得出最后一点的坐标
stu[z].y = b*sin(d);
if(stu[z].x >= 0-1e-8 && stu[z].x <= w+1e-8 && stu[z].y>=0-1e-8 && stu[z].y <= h+1e-8)
//注意精度,不然会wa。
{
printf("%.12f %.12f ", stu[0].x, stu[0].y);
printf("%.12f %.12f ", stu[1].x, stu[1].y);
printf("%.12f %.12f\n", stu[2].x, stu[2].y);
return 1;
}
return 0;
}
int main()
{
int t;
cin >> t;
while(t--)
{
double a, b, c;
scanf("%lf %lf %lf %lf %lf", &w, &h, &a, &b, &c);
if(solution(a, b, c, 0, 1, 2)) continue; //搜每一种情况
if(solution(a, c, b, 1, 0, 2)) continue;
if(solution(b, a, c, 0, 2, 1)) continue;
if(solution(b, c, a, 2, 0, 1)) continue;
if(solution(c, a, b, 1, 2, 0)) continue;
if(solution(c, b, a, 2, 1, 0)) continue;
}
return 0;
}