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: