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

C++でシーケンスをスタンプする


小文字のターゲット文字列を作成するとします。

最初は、シーケンスはn'?'です。マーク(nはターゲット文字列の長さ)。小文字のスタンプもあります。

各ターンで、シーケンスの上にスタンプを配置し、内のすべての文字をそのスタンプの対応する文字に置き換えることができます。最大10*nターンすることができます。例として、最初のシーケンスが「?????」で、スタンプが「abc」であるとすると、最初に「abc ??」、「?abc?」、「??abc」のような文字列を作成できます。ターン。

シーケンスにスタンプを付けることができる場合は、各ターンで左端の文字がスタンプされているインデックスの配列を返します。それが不可能な場合は、空の配列を返します。したがって、シーケンスが「ababc」で、スタンプが「abc」の場合、答えは[0、2]のようになります。これは、「?????」のように形成できるためです。 ->「abc??」 ->「ababc」。

したがって、入力がstamp ="abcd"、target ="abcdbcd"のような場合、出力は[3,0]

になります。

これを解決するには、次の手順に従います-

  • 配列retを定義する

  • ok:=true

  • n:=スタンプのサイズ

  • tsz:=0

  • okがゼロ以外の場合、実行-

    • ok:=false

    • x:=0

    • szの初期化:=スタンプのサイズ、sz> 0の場合、更新(szを1つ減らす)、実行-

      • 初期化i:=0の場合、i <=スタンプのサイズの場合、更新(iを1増やします)、実行-

        • newStamp:=長さiの「*」の文字列+インデックスitosz-1からのスタンプのサブ文字列+スタンプのサイズと同じサイズの「*」の文字列

        • pos:=ターゲット内のnewStampのインデックス

        • posがターゲットに存在する間、実行-

          • ok:=true

          • x:=x + sz

          • retの最後にposを挿入します

          • ターゲットを位置位置から位置+スタンプのサイズまで「*」で塗りつぶします。

          • pos:=ターゲット内のnewStampのインデックス

    • tsz:=tsz + x

  • 配列を逆にするret

  • return(tszがターゲットのサイズと同じ場合はret、それ以外の場合は1つの空白配列)

理解を深めるために、次の実装を見てみましょう-

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
   cout << "[";
   for(int i = 0; i<v.size(); i++){
      cout << v[i] << ", ";
   } cout << "]"<<endl;
}
class Solution {
   public:
   vector<int> movesToStamp(string stamp, string target) {
      vector<int> ret;
      bool ok = true;
      int n = stamp.size();
      int tsz = 0;
      while (ok) {
         ok = false;
         int x = 0;
         for (int sz = stamp.size(); sz > 0; sz--) {
            for (int i = 0; i <= stamp.size() - sz; i++) {
               string newStamp = string(i, '*') +
               stamp.substr(i, sz) + string(stamp.size() - sz - i, '*');
               int pos = target.find(newStamp);
               while (pos != string::npos) {
                  ok = true;
                  x += sz;
                  ret.push_back(pos);
                  fill(target.begin() + pos, target.begin() +
                  pos + stamp.size(), '*');
                  pos = target.find(newStamp);
               }
            }
         }
         tsz += x;
      }
      reverse(ret.begin(), ret.end());
      return tsz == target.size() ? ret : vector<int>();
   }
};
main(){
   Solution ob;
   print_vector(ob.movesToStamp("abcd", "abcdbcd"));
}

入力

"abcd", "abcdbcd"

出力

[3, 0, ]

  1. C++の迷路

    空のスペースと壁のある迷路の中にボールがあるとします。これで、ボールは上、下、左、右などの任意の方向に転がることで空のパスを通過できますが、壁にぶつかるまで転がりが止まりません。ボールが止まると、次の方向を選択できます。 ボールの位置、目的地、迷路を開始し、ボールが目的地に止まるかどうかを確認する必要があります。迷路は1つの2D配列で表されます。ここで、1は壁を示し、0は空きスペースを示します。迷路の境界はすべて壁です。開始座標と宛先座標は、行と列のインデックスで表されます。 したがって、入力が2D配列で表される迷路のようなものである場合 0 0 1 0 0

  2. C++のMazeIII

    空のスペースと壁のある迷路があり、その迷路の中にボールもあるとします。ボールは、上(u)、下(d)、左(l)、または右(r)の方向に転がることで空きスペースを通過できますが、壁にぶつかるまで転がり続けます。ボールが止まると、次の方向を選ぶことができます。その迷路にも1つの穴があります。ボールが穴に転がると、ボールは穴に落ちます。 したがって、ボールの位置、穴の位置、迷路がある場合、最短距離を移動することでボールがどのように穴に落ちるかを調べる必要があります。ここで、距離は、ボールがスタート(除外)からホール(含まれる)まで移動した空きスペースの数によって定義されます。 「u」、「d」、「l