ebisukeプログラミング初心者脱出黙示録

30歳を過ぎてから始めたプログラミングと競プロの記録。Pythonで取り組んでいます。Arduinoで電子工作も

AtCoder-ABC183 A - ReLU / B - Billiards【Python解答例】

先日AtCoder Beginner Contest183を受けました。

結果はA・B問題だけACでしたが、
そのときの私の解答を書きたいと思います。

AtCoder Beginner Contest183 A - ReLU

atcoder.jp

問題文意訳

整数xが0以上ならx、0より小さければ0となるReLU関数に対して、
整数 xが与えられるので ReLU(x)を求めてください。

制約

・xは整数
・−10≤x≤10

解答例

# coding:utf-8

x = int(input())

if x >= 0:
    print(x)
else:
    print("0")

解説

入力xが0以上ならそのままxを出力、
0より小さい値なら0を出力する問題でした。

AtCoder Beginner Contest183 B - Billiards

atcoder.jp

問題文

高橋君は2次元平面上でビリヤードをしています。
x軸は壁になっており、球をぶつけると入射角と反射角が等しくなるように球が跳ね返されます。
いま高橋君の球が (Sx,Sy)にあります。
ある座標を狙って球を撞くと、球はその座標へ向かって直線的に転がっていきます。
x軸で球をちょうど1回反射させたのち、(Gx,Gy)を通過させるためには、x軸のどこを狙えば良いでしょうか?

制約

・−10^6≤Sx,Gx≤10^6
・0

解答例

# coding:utf-8

sx, sy, gx, gy = map(int,input().strip().split())

if sx < gx:
    dx = gx - sx
    dy = sy + gy

    k = dy / dx
    xzero = sx + sy / k

    print(xzero)
else:
    dx = sx - gx
    dy = sy + gy

    k =  dy / dx
    xzero = sx - sy / k

    print(xzero)

解説

この問題は最初ボールが置いてある(Sx,Sy)のx軸に対称な点(Sx,-Sy)を考えて、
点(Sx,-Sy)と点(Gx,Gy)を結ぶ直線とx軸の交点を求める方法を思いつきました。
上記は実際のコンテストでの解答で、次のように2つの場合分けを行いましたが、
コンテスト後に考えてみると別にこの場合分けは不要だとわかりました。(なんともまぬけですね…)
・SxがGxより小さい場合
・SxがGxより大きい場合
とにかく、Syを-Syとした点を考えて、
まずSxとGxの差dxを求め、
次に-SyとGyの差(Gy-(-Sy)=Gy+Sy)dyを求めて、傾きkを求めました。
最終的にx軸との交点xzeroを上記のように求め、出力することでACでした。


その後C問題はすべての組み合わせ求め方がわからず、D問題はTLEとなり解けませんでした。
解説を見ると知らない方法の記載がありましたので次は新しく学習した内容を書き、
C問題とD問題を解いてみたいと思います。