0

塗りつぶしアルゴリズムはほぼ完成していますが、どこかに小さなエラーがあり、デバッグに約3時間費やしましたが、見つからないようです。

注:読み込むときは、0から15までの数字を使用して壁を定義します

1=上2=右4=下8=左(つまり、13は上/下/左の壁があることを意味します)

私のプログラム:

  • フィールド数を読み込んで最大の部屋を計算します(したがって、以下のすべてはフィールド数に対して繰り返されるサイクルです)。

  • 次に、部屋の寸法を取得します

  • これで、クラスフィールドに、周囲の壁(左から右下)と16未満の値を格納するオブジェクトの配列(セル)が作成されます。

  • ここで問題が発生すると思います。std::cinを介して値を読み取ります。

  • そして、すべてが読み込まれると、空(0)をスキャンして部屋を作成し、その周りの利用可能なスペースをチェックします(ウォールチェックを使用)

  • そして最後に最大値を返し、完了です。

私が使用する入力:

1
2 2
13 3
15 14

つまり、どこか、壁のチェック、またはオブジェクトセルの作成で何かがうまくいかないということです(私は思います)

これが私のスクリプトです。このようなばかげた質問をしなければならないのは残念です。

前もって感謝します

    // een simpele floodfill

    #include <stdlib.h>
    #include <iostream>
    #include <bitset>


class Cell {

    private:
      int  kamer, value;
      bool left, right, up, down;

    public:            
      // constructor
      Cell::Cell() {};
      // functions
      bool CanLeft()      { return left ; }
      bool CanRight()     { return right; }
      bool CanDown()      { return down ; }
      bool CanUp()        { return up   ; }
      int  GetRoom()       { return kamer; }
      void SetRoom(int x)  { kamer = x   ; }      
      void SetValue(int x, int room=0) { value  = x;
                             kamer = room;
                             std::bitset<sizeof(int)> bits(value); 
                             if (bits[3]) left  = true;
                             else         left  = false;
                             if (bits[2]) down  = true;
                             else         down  = false;
                             if (bits[1]) right = true;
                             else         right = false;
                             if (bits[0]) up    = true;
                             else         up    = false;
                           }
};

class Field {

    private:
      int Biggest_Chamber;
      int Y;
      int X;
      int temp;
      Cell playfield[][1];

    public:
      // constructor
      Field::Field(int SizeY, int SizeX) {
                    Y = SizeY;
                    X = SizeX;
                    Cell playfield[SizeY-1][SizeX-1];
                    }
      // Create a 2d array and fill it

      void Get_input() {

           for (int Yas = 0; Yas < Y; Yas++){

               for (int Xas = 0; Xas < X; Xas++){

                   std::cin >> temp;
                   playfield[Yas][Xas].SetValue(temp);         
               }
           } 
      };  
      void Start() { Mark(0,0,1); }

      void Mark(int y, int x, int nr) {
                  std::cout << nr;
                  temp = nr;
                  playfield[y][x].SetRoom(nr);
                  if (playfield[y][x].CanLeft())   {
                     if (playfield[y][x-1].GetRoom() != 0) {
                                                    Mark(y, x-1, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanDown()) {
                     if (playfield[y+1][x].GetRoom() != 0) {
                                                    Mark(y+1, x, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanRight())  {
                     if (playfield[y][x+1].GetRoom() != 0) {
                                                    Mark(y, x+1, nr);
                                                    std::cout << nr;
                                                    system("pause");}}
                  if (playfield[y][x].CanUp())   {
                     if (playfield[y-1][x].GetRoom() != 0) {
                                                    Mark(y-1, x, nr);
                                                    std::cout << nr;
                                                    system("pause");}} 
                  for (int vertical = 0; vertical < Y; vertical++) {
                      for (int horizontal = 0; horizontal < X; horizontal++) {
                          if (playfield[vertical][horizontal].GetRoom() == 0) Mark(vertical, horizontal, nr+1);                   
                      }      
                  }
      }         
      int MaxValue() {
          int counter[temp];
          int max = 0;

          for (int y = 0; y < Y; y++) {
              for (int x = 0; x < X; x++) {
                  counter[playfield[y][x].GetRoom()]++;
              }
          }

          for (int i = 0; i < temp; i++)
          {
              if (counter[i] > max)
                 max = counter[i];
          }

          return max;
     }            
};


    int main() {
    using namespace std;


    int NrKamers;
    int sizeY;
    int sizeX;

    std::cin >> NrKamers;
    for (int i = 0; i < NrKamers; i++){

        std::cin >> sizeY >> sizeX;

        Field floodfield(sizeY, sizeX);
        floodfield.Get_input();
        floodfield.Start();

        std::cout << floodfield.MaxValue() << std::endl;
    }
    return 0;
}
4

2 に答える 2

1

私はコードを処理する時間があまりありませんでしたが、最初の印象は、配列内の訪問した各位置をマークしていない (またはむしろマークを使用していない) ため、一方向に移動し、他の方向を処理している間です。元の正方形に戻る位置。左、右、上、下。左上隅から開始します。

左には移動できませんが、右には移動できます。その 2 番目の再帰レベルで、左に移動して振り出しに戻ることができます。次に、左に移動することはできませんが、右に移動できるため、正方形 2 に戻り、そこから正方形 1 に移動します... 無限に。

次の正方形に移動する前に、その正方形を訪問済みとしてマークする必要があります。また、移動しようとしている正方形が現在の実行で訪問されていないことを確認する必要があります。

セグメンテーション違反は、スタックを使い果たした後の無限再帰の結果です。

于 2011-05-09T08:25:28.057 に答える