はじめに
AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。
今回のお題
AtCoder Beginner Contest D - Opposite
Difficulty: 831
今回のテーマ、座標の変換
(x, y)を回転させた座標が答えとなります。
公式解説およびユーザ解説をrubyにトランスします。
公式解説
public.rb
include Math
n = gets.to_f
xy0 = gets.split.map(&:to_f)
xy2 = gets.split.map(&:to_f)
p = 2 * PI / n
q = [(xy0[0] + xy2[0]) / 2, (xy0[1] + xy2[1]) / 2]
r = sqrt((xy0[0] - q[0])**2 + (xy0[1] - q[1])**2)
t = atan2(xy0[1] - q[1], xy0[0] - q[0]) + p
puts [cos(t) * r + q[0], sin(t) * r + q[1]].join(' ')
Math.rb
include Math
Mathモジュールを呼び出しています。毎度、Math.PIなどと書かずPIと省略できます。
atan2は普段使わないし、公式解説はコードが載っていないので、AtCoder Beginner Contest 197 (Sponsored by Panasonic) 参戦記を参照しました。
ユーザ解説
user.rb
require 'complex'
include Math
n = gets.to_f
xy0 = gets.split.map(&:to_f)
xy2 = gets.split.map(&:to_f)
c0 = Complex(xy0[0], xy0[1])
c2 = Complex(xy2[0], xy2[1])
q = (c0 + c2) / 2
a = q + (c0 - q) * Complex.polar(1, 2 * PI / n)
puts [a.real, a.imag].join(' ')
Complex.rb
require 'complex'
こちらは複素数を用いた解法です。
class Complex
Complex.polarで回転させています。
自分のコード
my.rb
include Math
n = gets.to_f
xy0 = gets.split.map(&:to_f)
xy2 = gets.split.map(&:to_f)
p = 2 * PI / n
q = [(xy0[0] + xy2[0]) / 2, (xy0[1] + xy2[1]) / 2]
xa = cos(p) * (xy0[0] - q[0]) - sin(p) * (xy0[1] - q[1]) + q[0]
ya = sin(p) * (xy0[0] - q[0]) + cos(p) * (xy0[1] - q[1]) + q[1]
puts [xa, ya].join(' ')
公式解説の半径を使用していないバージョンです。
| RubyP | RubyU | RubyM | |
|---|---|---|---|
| コード長 (Byte) | 306 | 267 | 310 |
| 実行時間 (ms) | 63 | 66 | 63 |
| メモリ (KB) | 14640 | 14596 | 14712 |
まとめ
- ABC 197 D を解いた
- 座標変換 に詳しくなった