Nano Hash - криптовалюты, майнинг, программирование

Разрушение стены

Есть стена, построенная из чисел. 0 означает, что есть дыра, и блоки не могут сидеть на дырах. У кого-то есть специальный пистолет, который стреляет всеми блоками с числом за один выстрел.
Итак, у меня есть матрица, называемая стеной, и мне нужно написать пистолет. Я написал программу, но у меня проблема, и я не понимаю, почему это происходит. В моем коде

#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 );
}

Я действительно не понимаю, почему строка wall[ height - j - 1 ][ i ] = 0; работает для первых 4 столбцов в следующем примере и не работает для последнего.

Формат ввода:

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

Удалите все значения, соответствующие 1, 5, 1. А остатки стен должны упасть на дно.

Выход:

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

Пожалуйста, помогите мне решить эту проблему. Я не мог найти его для отладки кода.


  • Похоже, вам нужно использовать отладчик. 17.06.2017
  • @JamesRoot Я использовал отладчик 17.06.2017

Ответы:


1

Странный у вас алгоритм, я не понимаю, что вы пытаетесь сделать.

Простой способ достичь своей цели — выполнить итерацию слева направо от вашей стены, а затем для каждой итерации снизу вверх. Каждый раз, когда вы получаете 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, потому что это тип для index.
  2. Я рекомендую вам переключиться на std::vector и использовать для него итератор в C++.
17.06.2017
  • Я учусь, поэтому я пишу странные алгоритмы. Спасибо! И почему size_t тип для индекса? 17.06.2017
  • @Timʘtei en.cppreference.com/w/cpp/types/size_t. Помните, что этот тип не имеет знака. Может быть странно манипулировать для новичка. Но вы должны научиться им пользоваться. stackoverflow.com/a/22587575/7076153 17.06.2017
  • Из 2-й ссылки я понял, что нельзя использовать неподписанные циклы. 17.06.2017
  • @Timʘtei Да, это моя точка зрения, я не хочу на тебя влиять. Некоторые люди не согласны использовать беззнаковый тип. Я не хочу, чтобы вы думали, что должны использовать size_t, потому что некоторые люди не согласятся. Кстати, как и в случае с C++, эта проблема должна исчезнуть, потому что вы должны использовать std::vector и iterator, которые скроют это для вас. 17.06.2017
  • size_t оказывается типом возврата для всех stl-контейнеров size() и, конечно же, используется для индексации. Тем не менее индексы со знаком имеют некоторые преимущества в обнаружении ошибок и имеют отрицательные значения, которые можно использовать для обозначения неинициализированных. В большинстве случаев я предпочитаю хранить свои индексы как подписанные. 17.06.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..