реализация алгоритма моделирования на C/C++

Пусть ряд 8000 светильников. Изначально горит только тот, что расположен слева. Затем каждую секунду выполняется следующая операция: каждая лампа меняет состояние (включена или выключена), если за секунду до этого горела левая от нее. Крайняя левая лампа горит постоянно. Эта операция мгновенная. Процесс останавливается, когда лампа на правом конце загорается впервые. Сколько ламп горит?

Моя следующая реализация проблемы ложна, вы можете мне помочь?

#include <cstdio>

int t[8001][2];

int main()
{
    t[1][0] = 1;
    t[1][1] = 1;
    int cpt1 = 0, ip = 0;
    while (t[8000][0] != 1 && t[8000][1] != 1)
    {
        ip++; 
        for (int j=2;j<8001;j++)
        {
            if(t[j-1][!(ip&1)])
                t[j][(ip & 1)] = !t[j][!(ip & 1)];      
        }
    }   

    for(int j = 1;j < 8001; j++)
        cpt1 += t[j][1];

    printf("cpt=%d\n", cpt1);
}

person asterix    schedule 18.09.2017    source источник
comment
Первая мысль - это не 8001 лампа? В любом случае - ложно мало что говорит нам о том, почему это неправильно. Включите сообщение об ошибке или причину, по которой это неправильно. Изменить: nvm, вы используете 1-индексацию.....   -  person hnefatl    schedule 18.09.2017
comment
это не 8001 и не 4001, как показывает мой код, у меня нет решения, но я знаю, что это неправильно.   -  person asterix    schedule 18.09.2017
comment
Может помочь, если вы определите структуру для лампы с логическим полем isSwitchedOn. Таким образом, может быть легче обнаружить ошибку. Ваш код в текущем состоянии очень трудно понять.   -  person Zdeněk Jelínek    schedule 18.09.2017
comment
Зачем ему 2D-массив? Эта программа плохо читается. Обновить А, хорошо. Я думаю, это для двойной буферизации. Все равно не читабельно   -  person Eugene Sh.    schedule 18.09.2017
comment
Возможно, я использовал логическое значение, но для реализации состояния изменений (включено или выключено) ламп требуется двумерная структура.   -  person asterix    schedule 18.09.2017
comment
@EugeneSh.: Чтобы разделить текущее и следующее состояния.   -  person Scott Hunter    schedule 18.09.2017
comment
Тем не мение. начните с небольшого числа и распечатайте вывод для каждого цикла, чтобы отладить его. Если я правильно понимаю, крайняя левая лампа должна включать свет каждые два цикла, который будет распространяться вправо каждый цикл.   -  person Eugene Sh.    schedule 18.09.2017
comment
Тег #include<cstdio> + [C] - хммм.   -  person chux - Reinstate Monica    schedule 18.09.2017
comment
У меня 4001. Неясно, что подразумевает Моя следующая реализация проблемы, является ложной - пожалуйста, добавьте детали.   -  person chux - Reinstate Monica    schedule 18.09.2017
comment
Моя реализация дает 4001, но я знаю, что решение проблемы не в этом.   -  person asterix    schedule 18.09.2017
comment
@chux как это может быть 4001? Разве это не распространяется на 1 каждую секунду?   -  person Eugene Sh.    schedule 18.09.2017
comment
@asterix, но я знаю, что решение проблемы не в этом. --> Что вы ожидаете?   -  person chux - Reinstate Monica    schedule 18.09.2017
comment
@chux О, извини. Неверно прочитал сам вопрос.   -  person Eugene Sh.    schedule 18.09.2017
comment
C отличается от C++ (в котором вам лучше использовать контейнеры). Так что выберите язык и отредактируйте свой вопрос   -  person Basile Starynkevitch    schedule 18.09.2017
comment
Кстати, вопросы по исправлению моего кода не по теме   -  person Basile Starynkevitch    schedule 18.09.2017


Ответы (2)


Код отсутствует обновление, когда слева не меняется.

Код упрощен (смещение на основе нуля, использование bool) и исправлен ниже

#include<stdbool.h>
#include<stdio.h>
#define N 8000

bool t[N][2];

int main(void) {
  t[0][0] = true;
  t[0][1] = true;
  int ip = 0;

  while (t[N - 1][0] == 0 && t[N - 1][1] == 0) {
    ip = !ip;
    for (int j = 1; j < N; j++) {
      if (t[j - 1][!ip]) {
        t[j][ip] = !t[j][!ip];
      } else {
        t[j][ip] = t[j][!ip];  // add
      }
    }
  }

  int cpt1 = 0;
  for (int j = 0; j < N; j++) {
    cpt1 += t[j][1];
  }
  printf("N=%d cpt=%d\n", N, cpt1);
  return 0;
}

Выход

N=8000 cpt=2048
person chux - Reinstate Monica    schedule 18.09.2017

следующий предлагаемый код:

  1. чисто компилирует
  2. использует файлы заголовков C, а не файлы заголовков C++
  3. выполняет нужную операцию, но не максимально быстрый алгоритм
  4. обильно комментируется

А теперь предлагаемый код:

#include <stdio.h>

int t1[8000];   // initially all zeros
int t2[8000];


int main( void )
{
    // setup initial conditions
    int numLitLights = 0;
    t1[0] = 1;


    // while stop condition not true
    while ( t1[7999] != 1 )
    {
        // make one pass through lamps
        // update values
        for (int j=0; j<7999; j++)
        {
            if( t1[j] )
            {
                t2[j+1] = ( t1[j+1] )? 0 : 1;
            }
        }

        // update original
        for( int j=0; j< 8000; j++ )
        {
            t1[j] = t2[j];
        }
    }

    // count lit lamps
    for(int j = 0; j < 8000; j++)
    {
       if( t1[j] )
       {
           numLitLights++;
       }
    }

    // output number of lit lamps
    printf( "number of lit lamps: %d\n", numLitLights );
} // end function: main

Результат (количество зажженных ламп) равен

1024
person user3629249    schedule 20.09.2017
comment
ваша реализация и ваш результат 1024 ложны, см. решение chux - person asterix; 23.09.2017
comment
@астерикс. Вы можете быть правы. Покажите мне источник ошибки. Это логическая ошибка или мое непонимание параметров задачи? - person user3629249; 24.09.2017
comment
вы пропустили инициализацию t2[0]=1; с этим у вас есть правильное решение idem 2048. - person asterix; 25.09.2017
comment
@asterix, спасибо, меня всегда волнуют мелочи. Примечание. Первоначально я написал код с инициализацией t1[0] и t2[0] равным 1. Затем я сделал ошибку, думая, что мне не нужно инициализировать t2[0] вздох - person user3629249; 26.09.2017