C++
 Computer >> コンピューター >  >> プログラミング >> C++

カエルが家にたどり着くための最小ジャンプ回数を求めるC++コード


長さnの2進文字列Sと整数dが与えられます。数直線上で、カエルは地点1から出発し、地点nへの到達を目指しています。カエルは1回のジャンプでd以下の距離だけ右方向へ移動できます。地点1からnまでの各地点には、スイレンの花が咲いていれば「1」、なければ「0」が記されており、カエルはスイレンのある地点にしか着地できません。カエルが地点nに到達するために必要な最小ジャンプ回数を求めましょう。到達が不可能な場合は-1を返します。

例えば、入力が S = "10010101"、d = 4 の場合、出力は 2 になります。これは、位置1(インデックス0)からインデックス4へジャンプし、続けてインデックス7(n番目の地点)へジャンプすることで、合計2回のジャンプで目的地に届くためです。

解き方の手順

この問題は貪欲法(グリーディ法)を用いて解くことができます。具体的な手順は以下の通りです。

  • 現在位置xを0(スタート地点)、ジャンプ回数yを0で初期化します。
  • 現在位置からd先の地点にスイレン(「1」)がある場合は、そこへジャンプし、カウントを1増やします。
  • d先の地点にスイレンがない場合は、スイレンのある地点が見つかるまで1つずつ手前に戻って探します。
  • これを目的地(インデックスn-1)に到達するまで繰り返します。
  • ジャンプ回数がnを超えた場合は到達不可能と判断し、-1を返します。
n := s のサイズ
x := 0
y := 0
while (x < n - 1 かつ y <= n), do:
    もし s[x] が '1' ならば:
        x := x + d
        y を 1 増やす
    そうでなければ:
        x を 1 減らす
if y >= n, then:
    -1 を返す
それ以外の場合:
    y を返す

実装例

理解を深めるために、以下のC++による実装を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
int solve(string s, int d){
   int n = s.size();
   int x = 0, y = 0;
   while (x < n - 1 && y <= n){
      if (s[x] == '1')
         x += d, ++y;
      else
         --x;
   }
   if (y >= n)
      return -1;
   else
      return y;
}
int main(){
   string S = "10010101";
   int d = 4;
   cout << solve(S, d) << endl;
}

入力

"10010101", 4

出力

2

  1. C++で無限数直線上のターゲットに到達するための最小移動回数を求める方法

    問題の概要 無限に続く数直線(−∞ から +∞)上で、位置 0 からスタートして指定されたターゲットに到達することを考えます。i 回目の移動では、左または右にちょうど i ステップ進むことができます。このとき、ターゲットに到達するために必要な最小の移動回数を求めます。 例えば、ターゲットが 2 の場合、最小ステップ数は 3 になります。移動の流れは「0 → 1 → -1 → 2」となります。 解法のアプローチ この問題を解くためには、以下の重要なポイントを押さえておく必要があります。 ターゲットが負の数であっても、数直線は原点を中心に対称であるため、正の数として扱って問題ありません。 基本

  2. Pythonで解く!虫が家にたどり着くための最小ジャンプ回数を求めるアルゴリズム

    問題概要 「forbidden」という配列が与えられます。forbidden[i] は、虫(バグ)がその位置 forbidden[i] へジャンプしてはいけないことを示します。さらに、a、b、x という3つの値も与えられます。虫の家は数直線上の位置 x にあり、虫は初期状態で位置 0 にいます。虫は以下のルールに従ってジャンプできます。 正確に a だけ前(右)方向へジャンプできる 正確に b だけ後ろ(左)方向へジャンプできる 後ろ向きのジャンプを2回連続で行うことはできない 配列 forbidden に含まれる位置にはジャンプできない 家より先へ前方向にジャンプすることは可能だが、負の位