2017-06-17 14 views
-1

数字で建てられた壁があります。 0は、穴があり、穴に穴ができないことを意味します。誰かが1発の数字ですべてのブロックを発射する特別な銃を持っています。
私は壁と呼ばれる行列を持ち、銃を書く必要があります。私はプログラムを書いたが、問題があり、なぜそれが起こっているのか分からない。ラインwall[ height - j - 1 ][ i ] = 0;次の例では最初の4列のために働いていると、それは最後の1のために動作しませんなぜ私のコード壁が破壊される

#include <iostream> 
#include <cstdio> 

using namespace std; 

int createWall(int &height, int &length, int wall[][ 100 ], int shots) 
{ 
    int i; 
    int j; 
    cin >> height; 
    cin >> length; 
    cin >> shots; 
    for (i = 0; i < height; i++) 
    { 
     for (j = 0; j < length; j++) 
     { 
      cin >> wall[ i ][ j ]; 
     } 
    } 
    return shots; 
} 


void wallNow(int height, int length, int wall[][ 100 ]) 
{ 
    int i; 
    int j; 
    for (i = 0; i < height; i++) 
    { 
     for (j = 0; j < length; j++) 
     { 
      cout << wall[ i ][ j ] << " "; 
     } 
     cout << "\n"; 
    } 
} 

void destroyWall(int height, int length, int wall[][100], int shots) 
{ 
    int i; 
    int j; 
    int k; 
    int x; 
    int aimedBlocks;//number to be "destroyed" 
    //set all aimedBlocks to 0 
    for (x = 0; x < shots; x++) 
    { 
     cin >> aimedBlocks; 
     for (i = 0; i < height; i++) 
     { 
      for (k = 0; k < length; k++) 
      { 
       if (wall[ i ][ k ] == aimedBlocks) 
       { 
        wall[ i ][ k ] = 0; 
       } 
      } 
     } 
    } 

    int counter;//I use this variable because at some point I have a 0 followed only by 0's 
    for (i = 0; i < length; i++) 
    { 
     j = height - 1; 
     counter = 0; 
     //if I find a 0 then I move all elements higher that it one step down 
     while (counter < height) 
     { 
      if (wall[ j ][ i ] == 0) 
      { 
       for (k = j; k > 0; k--) 
       { 
        wall[ k ][ i ] = wall[ k - 1 ][ i ]; 
       } 
       wall[ height - j - 1 ][ i ] = 0; 
      } 
      else 
       j--;//I don't always go up ene step because the "block" droped in place of 0 may be 0 
      counter++; 
     } 
    } 
} 

int main() 
{ 
    int height; 
    int length; 
    int wall[ 100 ][ 100 ]; 
    int shots = 0; 
    shots = createWall(height, length, wall, shots); 
    destroyWall(height, length, wall, shots); 
    wallNow(height, length, wall); 
} 

で、私は本当に理解していません。

フォーマット入力:

height length shots 
wall_0_0 ... wall_0_length 
... ... ... 
wall_height ... wall_height_length 
shot_0 ... shot_shots 

入力:

4 5 3 
3 5 4 5 1 
2 1 1 5 3 
1 1 5 5 1 
5 5 1 4 3 
1 5 1 

151と一致するすべての値を削除します。壁の残骸は底に落ちなければならない。

出力:

0 0 0 0 0 
0 0 0 0 0 
3 0 0 0 0 
2 0 4 4 3 

が予想される:

0 0 0 0 0 
0 0 0 0 0 
3 0 0 0 3 
2 0 4 4 3 

私はこの問題を解決する助けてください。私はそれがコードをデバッグ見つけることができませんでした。

+1

デバッガを使用する必要があるようです。 –

+0

@JamesRoot私はデバッガを使用しました –

答えて

2

あなたのアルゴリズムは奇妙です、私はあなたが何をしようとしているのか分かりません。

目的を達成するための簡単な方法は、壁の左から右に反復することです。次に、それぞれを下から上に繰り返します。 0を取得するたびに、トップにゼロ以外の値を検索し、見つかった場合はスワップします。

例(非常に基本的に向上させることができる):

for (size_t i = 0; i < length; i++) { // i is for iterate from left(0) to right(length - 1) 
    size_t j = height; // j is for iterate from bot(height - 1) to top(0) 
    while (j-- > 0) { 
    if (wall[j][i] == 0) { 
     size_t k = j; // k is for found a non zero value from j - 1 to the top(0) 
     while (k-- > 0) { 
     if (wall[k][i] != 0) { 
      wall[j][i] = wall[k][i]; 
      wall[k][i] = 0; 
      break; 
     } 
     } 
    } 
    } 
} 

注:

  1. これはインデックスのタイプですので、私はsize_tを使用しています。
  2. std::vectorに切り替え、C++でiteratorを使用することをお勧めします。
+0

これは私が奇妙なアルゴリズムを書く理由です。ありがとう!なぜ、 'size_t'はインデックスの型ですか? –

+0

@Timʘteihttp://en.cppreference.com/w/cpp/types/size_tこの型は符号なしであることに注意してください。初心者のために操作するのが奇妙なことがあります。しかし、あなたはそれを使う方法を学ぶべきです。 https://stackoverflow.com/a/22587575/7076153 – Stargateur

+0

2番目のリンクから理解したことは、unsigned inループを使用しないことです。 –

関連する問題