【C++】ロボットが移動後に原点(0,0)へ戻るかどうかを判定するアルゴリズム
あるロボットがあり、その初期位置は (0, 0) だとします。ここで、ロボットの一連の移動手順が与えられたとき、すべての移動を完了した後、このロボットが元の位置 (0, 0) に戻っているかどうかを判定する必要があります。
移動の手順は文字列として与えられ、moves[i] が i 番目の移動を表します。各記号の意味は以下の通りです。
- R:右へ移動
- L:左へ移動
- U:上へ移動
- D:下へ移動
ロボットがすべての移動を終えた時点で原点に戻っていれば true を返し、そうでなければ false を返します。
たとえば、入力が "RRULLD" の場合、出力は true になります。これは、右へ2単位進み、次に上へ移動し、その後左へ2単位、最後に下へ移動することで、元の開始位置に戻るためです。
解決のためのアプローチ
この問題を解くには、以下の手順に従います。
- 変数
lに移動文字列の長さを代入します。 lが 0 の場合(移動がない場合)は、trueを返します。- 水平方向のカウンタ
lftと垂直方向のカウンタupをそれぞれ 0 で初期化します。 - i = 0 から i < l の間、以下の処理を繰り返します。
moves[i]が 'L' なら、lftを 1 増やすmoves[i]が 'R' なら、lftを 1 減らすmoves[i]が 'U' なら、upを 1 増やすmoves[i]が 'D' なら、upを 1 減らす
- ループ終了後、
lftが 0 かつupが 0 であればtrueを返します。 - それ以外の場合は
falseを返します。
この方法では、左右の移動が打ち消し合い、上下の移動も打ち消し合うことがカウンタによって確認できます。計算量は O(n)、空間計算量は O(1) と非常に効率的です。
実装例
理解を深めるために、以下の実装を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool judgeCircle(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] == 'L') {
lft++;
}
if (moves[i] == 'R') {
lft--;
}
if (moves[i] == 'U') {
up++;
}
if (moves[i] == 'D') {
up--;
}
}
if (lft == 0 && up == 0) {
return true;
}
return false;
}
};
main(){
Solution ob;
cout << (ob.judgeCircle("RRULLD"));
}入力
"RRULLD"
出力
1
出力が 1(つまり true)となり、ロボットが正しく原点に戻ったことが確認できます。
-
C++のvoid関数でreturnする方法|値以外を返すテクニックを解説
void関数が「void(空)」と呼ばれるのは、何も返さないためです。しかし、「void関数は何も返せない」という説明は、必ずしも正しいとは言えません。void関数から値を返すことはできませんが、値以外のものを返したり、return文を活用したりすることは可能です。本記事では、その具体的な方法をサンプルコードとともに解説します。void関数でもreturn文は使えるvoid関数は値を返すことができませんが、return文そのものを記述することは可能です。引数なしのreturn文は「この時点で関数を終了する」という意図を明示的に示す働きがあり、処理の流れが分かりやすくなるため、コードの可読性向上
-
C++でオブジェクトを返す方法とは?サンプルコードでわかりやすく解説
オブジェクトとは、クラスから生成される実体(インスタンス)のことです。メモリが割り当てられるのはクラスを定義した時ではなく、オブジェクトを実際に生成した時点です。 C++では、関数内でreturnキーワードを使うことで、オブジェクトをそのまま戻り値として返すことができます。以下に、Pointクラスを使った具体的なサンプルコードを示します。 サンプルコード #include <iostream> using namespace std; class Point { private: int x; int y; public: Point(in