よわよわ大学生の掃き溜め

自分の興味があることを備忘録も兼ねて記録するところ。

ABC197

2021/3/27に開催されたAtCoder Beginner Contest 197の考え方をメモるエントリです。

A - Rotate

string s;
cin >> s;
cout << s[1] << s[2] << s[0] << endl;

特に難しいことはありません。もう少しスマートな書き方がある気はしますがACすればいいんです((

B - Visibility

マス目\displaystyle{
(X, Y)
}は上から\displaystyle{
X
}マス、左から\displaystyle{
Y
}マスであることに注意します。

マス目の状態を配列にぶちこんで、マス目\displaystyle{
(X, Y)
}の上下左右に.がいくつあるかを数えればいいです。

D - Opposite

正n角形についての問題です。

\displaystyle{
x _ {0}, y _ {0}, x _ {\frac{n}{2}}, y _ {\frac{n}{2}}
}から正n角形の中心を求める

 →その中心から見た\displaystyle{
p _ {0}
}の相対座標を求める

 →それを\displaystyle{
\frac{360}{n}
}度回転させる

 →相対座標を絶対座標に戻す

という手順を踏みました。

int n, x0, y0, xh, yh;
cin >> n >> x0 >> y0 >> xh >> yh;

double xc = (x0 + xh) / 2.0;
double yc = (y0 + yh) / 2.0;

double xc0 = x0 - xc;
double yc0 = y0 - yc;

double rad = 2 * M_PI / n;
double xc1 = xc0 * cos(rad) - yc0 * sin(rad);
double yc1 = xc0 * sin(rad) + yc0 * cos(rad);

double x1 = xc1 + xc;
double y1 = yc1 + yc;

printf("%.10lf %.10lf\n", x1, y1);

回転には回転行列的な考え方を使いました。

\displaystyle{
\begin{align}
    \left(
        \begin{array}{c}
            x \\
            y
        \end{array}
    \right) = \left(
        \begin{array}{rr}
            \cos{\theta} & -\sin{\theta} \\
            \sin{\theta} & \cos{\theta}
        \end{array}
    \right) \left(
        \begin{array}{c}
            X \\
            Y
        \end{array}
    \right)
\end{align}
}

この式は、点\displaystyle{
(X, Y)
}を原点\displaystyle{
O
}を中心として角\displaystyle{
\theta
}だけ回転させると点\displaystyle{
(x, y)
}になることを表しています。

これを計算すると

\displaystyle{
\begin{align*}
    \begin{cases}
        x = X \cos{\theta} - Y \sin{\theta} & \\
        y = X \sin{\theta} + Y \cos{\theta} &
    \end{cases}
\end{align*}
}

となるので、コード中ではこの式を使用しました。