D - RLE Moving Editorial
by
shobonvip
公式解説のように区間に分けた後、次の問題を解けばよいです。
高橋君は \((R_t, C_t)\) から \(D_t\) へ、青木君は \((R_a, C_a)\) から \(D_a\) へ \(1\) 回の行動で \(1\) マスごとに移動することを \(T\) 回繰り返します。
移動後に高橋君と青木君の位置が一致する回数を求めてください。
また、 \(T\) 回移動後の高橋君と青木君の座標を求めてください。
大変な(しかしこれでも正しい)解法としては、 \(D_t, D_a\) がそれぞれ \(4\) 通りあるため、 \(4^2=16\) 通りすべてについて1つ1つ記述することです。しかし、これではバグを多く埋め込みやすいです。
次のように実装を工夫すると少し楽になると思います。
\(1\) 回の移動の変化を考える
\(1\) 回移動で座標が、高橋君は \(((dr)_t, (dc)_t)\) だけ変化し、青木君は \(((dr)_a, (dc)_a)\) だけ変化するとします。 \((dr)_t, (dc)_t\) は次のように表されます( \((dr)_a, (dc)_a\) も同様です)
\[ (dr)_t = \begin{cases} -1 & (D_t = `U`)\\ 1 & (D_t = `D`)\\ 0 & (他) \end{cases} \]
\[ (dc)_t = \begin{cases} -1 & (D_t = `L`)\\ 1 & (D_t = `R`)\\ 0 & (他) \end{cases} \]
「 \(x\) 回移動後、高橋君と青木君の座標が一致している」という条件は次の連立方程式で表されます。
\[ \begin{cases} R_t + x (dr)_t = R_a + x (dr)_a\\ C_t + x (dc)_t = C_a + x (dc)_a \end{cases} \]
変形すると
\[ \begin{cases} R_t - R_a = x ((dr)_a - (dr)_t)\\ C_t - C_a = x ((dc)_a - (dc)_t) \end{cases} \]
です。 \(1 \le x \le T\) を満たす整数 \(x\) であって、この連立方程式を満たすものの個数を数え上げればよいです。
\((dr)_a - (dr)_t = 0\) の場合
1個目の条件は \(R_t = R_a\) となるため、これが満たされてなかったら条件を満たす \(x\) は存在しません。そうでなかったら、すべての \(x\) について満たされます。
\((dr)_a - (dr)_t \ne 0\) の場合
\[ x = \frac{R_t - R_a}{(dr)_a - (dr)_t}\]
と求められます。もしこれが整数でない、すなわち、 \(R_t - R_a\) が \((dr)_a - (dr)_t\) で割り切れない場合、条件を満たす \(x\) は存在しません。
そうでない場合、 \(x\) は整数となります。ここで \(1 \le x \le T\) でなかったら、条件を満たす \(x\) は存在しません。 \(1 \le x \le T\) であったら、その \(x\) のみが条件を満たす \(x\) の候補になります。
以上のことを \(2\) 番目の方程式にも行い、
- 「すべての \(x\) について条件が満たされる」なら \(T\) 個
- 「ある \(1\le x\le T\) があり、 \(x\) のみで条件を満たす」なら \(1\) 個
- 「条件を満たす \(x\) が存在しない」なら \(0\) 個
というふうになります。
擬似コードとしては
f(rt,ra,ct,ca,dtr,dtc,dar,dac,T) {
is_all_ok_r = 0
is_all_ok_c = 0
r_value = -1
c_value = -1
if (dra - drt == 0) {
if (rt - ra != 0) {
return 0
} else {
is_all_ok_r = 1
}
} else {
if ((rt - ra) % (dra - drt) != 0) {
return 0
} else {
r_value = (rt - ra) / (dra - drt)
if (not (1 <= r_value and r_value <= T)) {
return 0
}
}
}
if (dca - dct == 0) {
if (ct - ca != 0) {
return 0
} else {
is_all_ok_c = 1
}
} else {
if ((ct - ca) % (dca - dct) != 0) {
return 0
} else {
c_value = (ct - ca) / (dca - dct)
if (not (1 <= c_value and c_value <= T)) {
return 0
}
}
}
if (is_all_ok_r == 1) {
if (is_all_ok_c == 1) {
return T;
} else {
return 1;
}
} else {
if (is_all_ok_c == 1) {
return 1;
}else {
if (r_value == c_value) {
return 1;
} else {
return 0;
}
}
}
}
このようになります。
「\(T\) 回移動後の高橋君と青木君の座標」についてはそれぞれ
\[(R_t + T (dr)_t, C_t + T(dc)_t)\]
\[(R_a + T (dr)_a, C_a + T(dc)_a)\]
となるため、簡単に求められます。
posted:
last update:
