問題蟲洞: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;
}