2019牛客暑期多校訓練營(第五場)——I(聽說很暴力)

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

 

發佈了165 篇原創文章 · 獲贊 35 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章