u_sho競プロぶろぐ

21歳。みゃーくぴとぅ。ゆる~く続けますたぶん。  デザイン変えました(2019/2/25)これでいきます

AtCoder Beginner Contest 183 (A, B のみ)

久しぶりすぎてはてな記法を忘れました.u-shoです.
調べていたら数式を書けるようになりました.進歩!
AtCoder Beginner Contest 183 - AtCoder に参加したので少し書こうと思います.

A - ReLU

問題概要

次のような関数 \mathrm{ReLU} があります.


\mathrm{ReLU}(x) = \begin{cases} x & (x\geq 0) \\ 0 & (x < 0) \end{cases}
x が入力として与えられるので \mathrm{ReLU}(x) を出力します.

解法

\mathrm{ReLU} 関数は x\geq0 なら x,x<0 なら 0 を返すので,次のようにも書けますね.


\mathrm{ReLU}(x) = \max (x, 0)

なのでプログラムはこんな感じです.

#include <iostream>
int main(){
    int x;
    std::cin >> x;
    std::cout << std::max(x, 0) << "\n";
    return 0;
}

B - Billiards

問題概要

S:(S_x,\,S_y) と点 G:(G_x,\,G_y) があります (S_y>0,\;G_y>0).
x 軸で反射させて,点 S から点 G にボールを通過させるには,x 軸のどこを狙えばいいでしょう?

解法

x 軸で反射させて,点 (S_x,\,S_y) から点 (G_x,\,G_y) にボールを通過させるには,点 (S_x,\,S_y) から点 (G_x,\,-G_y) を結ぶ直線の x 切片を狙えばいいですね.
なので,点 (S_x,\,0) から x 軸方向に (G_x-S_x)\times\left|\frac{G_y-S_y}{S_y}\right| だけ移動したところです.

符号と出力桁数と精度に気をつけて

#include <bits/stdc++.h
int main() {
    using namespace std;

    long double Sx, Sy, Gx, Gy;
    cin >> Sx >> Sy >> Gx >> Gy;
    cout << fixed << setprecision(10) << Sx + (Gx-Sx) / (Gy + Sy) * Sy << "\n";

    return 0;
}

なお,適切に式変形することで S_x + (G_x-S_x) / (G_y + S_y) * Sy = (S_x G_y + G_x S_y) / (S_y + G_y) とできます

あとがき

久々に書いて疲れたのでこの辺で終わります.ごめんにゃ