これは…B問題の難易度なのか……?
https://atcoder.jp/contests/abc108/tasks/abc108_b
全くわからんので解説を咀嚼します。
ユーザ解説
https://blog.hamayanhamayan.com/entry/2018/09/02/223200
以下は入力例2をもとに考えてみます。
ベクトルについて
ベクトルとは、向きと大きさを持つ何かです。始点と終点があり、それを結ぶ直線矢印で表します。大きさは長さで表現します。
例の直線について、(x1, y1)を始点とするベクトルで表現してみると以下のような感じです。
ベクトルは位置には依存せず、向きと大きさが同じなら同じベクトルです。したがって座標平面上で任意の平行移動ができます。たとえば始点を原点に移動させてみます。
この時、移動後のベクトルの終点の座標は(4, 3)となっていますが、これをベクトルの成分表示といいます。始点が原点と決まっていれば、あとは終点の座標さえわかればベクトルの向きも大きさもわかる、つまりベクトルを特定できます。(4, 3)がベクトルの識別子になるわけですね。
ということで、解説の初手で(x2 - x1, y2 - y1)を求めているのはこのベクトルの成分表示を求めています。例だと(6 - 2, 6 - 3)なのでたしかに(4, 3)になります。成分表示を求めているのは、後述の回転行列がそれ前提だからのようです。
回転行列について
さて、ここで(4, 3)を反時計回りに90°回転させたいです。もっと言うと、回転後のベクトルの成分表示がほしい。まさにそれを求めることができるのが回転行列です。(x, y)のベクトルを反時計回りにθだけ回転させた後の座標(x', y')は以下の式で求められます。
\begin{pmatrix}
x' \\
y' \\
\end{pmatrix} =
\begin{pmatrix}
cosθ & −sinθ \\
sinθ & cosθ \\
\end{pmatrix}
\begin{pmatrix}
x \\
y \\
\end{pmatrix}
回転行列というだけあって、行列で表現します。
これは
\begin{pmatrix}
cosθ & −sinθ \\
sinθ & cosθ \\
\end{pmatrix}
\begin{pmatrix}
x \\
y \\
\end{pmatrix}
という2つの行列を掛けた結果ということですね。
後者は座標なので
\begin{pmatrix}
4 \\
3 \\
\end{pmatrix}
です。
sinθとかcosθですが、今回はθは90°です。90°の場合、sinθは1でcosθは0です。なので
\begin{pmatrix}
0 & −1 \\
1 & 0 \\
\end{pmatrix}
です。
したがって
\begin{pmatrix}
0 & −1 \\
1 & 0 \\
\end{pmatrix}
\begin{pmatrix}
4 \\
3 \\
\end{pmatrix}
を計算した結果がほしい値です。
行列の掛け算はあまり直感的ではない計算方法になります。
\begin{pmatrix}
a & b \\
c & d \\
\end{pmatrix}
\begin{pmatrix}
x \\
y \\
\end{pmatrix} =
\begin{pmatrix}
ax + by \\
cx + dy \\
\end{pmatrix}
となるらしいです。今回は
\begin{pmatrix}
0 & −1 \\
1 & 0 \\
\end{pmatrix}
\begin{pmatrix}
4 \\
3 \\
\end{pmatrix} =
\begin{pmatrix}
0 × 4 + -1 × 3 \\
1 × 4 + 0 × 3 \\
\end{pmatrix} =
\begin{pmatrix}
-3 \\
4 \\
\end{pmatrix}
となります。
なので(4, 3)のベクトルを反時計回りに90°回転させると、(-3, 4)になります。
(あんまり90°っぽく見えないのはこの座標が雑に作ったものだからです…)
ただ、(-3, 4)はまだ答えではありません。ほしい値のベクトルの始点は原点ではなく(6, 6)です。(-3 + 6, 4 + 6) = (3, 10)がほしい答えの1つ目です。(これはベクトルの平行移動です)
ほしい値の2つ目を得るには、回転後のベクトルをさらに90°回転させます。すなわち
\begin{pmatrix}
0 & −1 \\
1 & 0 \\
\end{pmatrix}
\begin{pmatrix}
-3 \\
4 \\
\end{pmatrix} =
\begin{pmatrix}
0 × -3 + -1 × 4 \\
1 × -3 + 0 × 4 \\
\end{pmatrix} =
\begin{pmatrix}
-4 \\
-3 \\
\end{pmatrix}
です。
どう見ても歪んでるけど脳内補正をお願いします…本来はまっすぐになるはず。
で、これをまた平行移動させます。今度は始点が(3, 10)なので、(-4 + 3, -3 + 10) = (-1, 7)です。
ということで求める答えは(3, 10)および(-1, 7)です。出力例と一致しました。
実装
fun main() {
val (x1, y1, x2, y2) = readln().split(" ").map { it.toInt() }
var dx = x2 - x1
var dy = y2 - y1
var x = x2
var y = y2
for(i in 0 until 2) {
val rdx = -dy
val rdy = dx
x = rdx + x
y = rdy + y
print("$x $y")
if(i == 0) {
print(" ")
}
dx = rdx
dy = rdy
}
println()
}
https://atcoder.jp/contests/abc108/submissions/53408121
Discussion