【C++】指定された方向に移動した後、開始位置(0,0)に戻れるかどうかを判定する方法
平面上の座標 (0, 0) を起点として、4種類の文字で構成された文字列が与えられます。この文字列は連続する移動方向を表しており、各文字は以下の方向に対応しています。
- E:東(east)
- W:西(west)
- N:北(north)
- S:南(south)
この問題では、与えられたすべての移動指示を実行した後、再び開始位置 (0, 0) に戻ることができるかどうかを判定します。
具体例
たとえば入力が "EENWWS" の場合、出力は true になります。移動の流れを追うと以下のようになります。
- 東へ2単位移動(E、E)
- 北へ1単位移動(N)
- 西へ2単位移動(W、W)
- 南へ1単位移動(S)
東西方向の移動が相殺され、南北方向の移動も相殺されるため、最終的に元の位置に戻ることになります。
解法のアプローチ
この問題は非常にシンプルなカウンタ管理で解決できます。考え方は次のとおりです。
- 文字列の長さを
lとします。lが 0 の場合は移動がないため true を返します。 - 水平方向の変位を表す
lftと、垂直方向の変位を表すupをそれぞれ 0 で初期化します。 - 文字列を先頭から順に走査し、各文字に応じてカウンタを更新します。
- 'W' なら
lftを +1 - 'E' なら
lftを -1 - 'N' なら
upを +1 - 'S' なら
upを -1
- 'W' なら
- 走査終了後、
lftとupがどちらも 0 であれば true、そうでなければ false を返します。
つまり、「東西の移動回数が一致し、かつ南北の移動回数も一致していれば原点に戻れる」という性質を利用しています。
C++による実装例
以下に実際の実装を示します。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool solve(string moves) {
int l = moves.length();
if (l == 0) {
return true;
}
int lft = 0, up = 0;
for (int i = 0; i < l; i++) {
if (moves[i] == 'W') {
lft++;
}
if (moves[i] == 'E') {
lft--;
}
if (moves[i] == 'N') {
up++;
}
if (moves[i] == 'S') {
up--;
}
}
if (lft == 0 && up == 0) {
return true;
}
return false;
}
};
main(){
Solution ob;
cout << (ob.solve("EENWWS"));
}入力
"EENWWS"
出力
1
出力が 1(true)となり、開始位置に戻れることが確認できました。
計算量について
このアルゴリズムは文字列を一度だけ走査するため、時間計算量は O(n)(n は文字列の長さ)、使用する追加メモリは定数個の変数のみなので空間計算量は O(1) となります。非常に効率的な解法です。
-
C++でグリッド内の指定方向に実行可能な移動回数をカウントする方法
サイズ n × m のグリッドと、開始座標 (x, y) を表す変数が与えられます。さらに、グリッド内を移動するために使用できるステップのペア(例:(1,1)、(2,2) など)も与えられます。各ペアは、x 軸と y 軸方向に進む単位移動量を表します。ゴールは、境界 [1, n] × [1, m] の範囲内でグリッド内を移動できる合計ステップ数を求めることです。 たとえば、n = 5、m = 4、現在位置が (2, 2)、選択したステップが (1, -1) の場合を考えてみましょう。このステップを 1 回適用すると (3, 1) に移動できますが、もう 1 回適用すると (4, -1) となり
-
C++で指定サイズの長方形内に作成できる菱形の個数を数える方法
問題の概要 高さ×幅の寸法をもつ長方形が与えられます。この長方形は2次元座標系上に配置されており、左下の頂点が原点 (0,0) に位置します。今回の目的は、次のすべての条件を満たす菱形がこの長方形内にいくつ作れるかを数えることです。 菱形の面積が0より大きいこと。 菱形の対角線がx軸およびy軸に平行であること。 菱形のすべての頂点が整数座標を持つこと。 入出力例 入力:縦=3、横=3 出力:指定サイズの長方形内に作れる菱形の個数:4 説明:下の図は縦3×横3の長方形です。面積が0より大きく、対角線が両軸に平行で、頂点が整数座標である菱形が4つ存在します。 1つ目 [ (1,0), (2,1