Задача 21 Урок 13.1

Задача 21 Урок 13.1

Пользователь передает целые положительные число N и M, выведете на экран последовательность от 1 до N, так чтобы ширина "ёлочки" увеличивалась до M чисел, то уменьшалась до 1. Например, для M=3 и N=25 получим:

var N, M, i ,c ,k :integer;
    f: boolean;

begin
  writeln('vvedi massu elki N ');
  readln(N);
  writeln('vvedi shiriny M ');
  readln(M);
  i := 1;    // начало отсчета последовательности
  k := 1;    // динамический построчный ограничитель ширины елки от одного до N c шагом +1 и -1
  while(i <= N) do
    begin
      if((k <= M) and (not f) )then   // увеличение елки. (not f) чтобы не вернуться в это условие при уменьшении елки
        begin
          c := 0; //внутриусловный посимвольный счетчик ширины елки
          repeat
            if(i <= N) then // когда достигнут максимум по массе елки закончить
              begin
                write(i, ' ');
                i := i + 1;    // увеличиваем последовательность чисел
                c := c + 1;    // увеличиваем ширину ветки елки на 1 (не мах)
              end;
          until (c = k);   // условие выхода по отресовке ветки
          writeln();
          k := k + 1;      //увеличиваем ограничительную ширину строки на 1
        end
      else  // уменьшение елки
        begin
          c := 0;  //внутриусловный посимвольный счетчик ширины елки
          repeat
            if(i <= N) then  // когда достигнут максимум по массе елки закончить
              begin
                write(i, ' ');
                i := i + 1;  // увеличиваем последовательность чисел
                c := c + 1;  // увеличиваем ширину ветки елки на 1 (не мах)
              end;
          until (c = (k-2));  // (к-2) из за особеностей кода.  условие выхода по отресовке ветки
          writeln();
          k := k - 1;   //уменьшаем ограничительную ширину строки на 1
          f := true;     // флаг чтобы не вернуться в условие по увеличению елки
          if(k=2) then    // условие чтобы начать снова ёлку увеличивать(выйдя из уменьшения)
            f := false;
        end;
    end;
  readln();
end. 
vedro-compota's picture

  • первый цикл отвечает за список строк
  • второй цикл отвечает за вывод конкретной строки (напр. знает начальное и конечное значение или начальное значение и количество элементов в очередной строке)

перепишите чтобы внутри основного цикла был один цикл, а не два.

_____________
матфак вгу и остальная классика =)

var N, M, i ,L ,k :integer;
begin
  writeln('vvedi massu elki N ');
  readln(N);
  writeln('vvedi shiriny M ');
  readln(M);
  l := 2;  // ограничитель символов в строке     (начать с 2х и закончить 1)
  k := 0; //  посимвольный счетчик на строке
  i := 2;
  writeln(1);
  while (i <= N) do
    begin
      if(k <= L) then // условие входа для увеличения   елки
        if(k = L) then  //увеличиваем длину строки на 1
          begin
            i := i - 1;
            L := L + 1;
            if(L > M) then //в последней итерации на увеличение меняем зайдет сюда и переключит на уменьшение
              begin
                L := M - 1;   // создается разница в 2 раза между L и k
                k := L * 2;
              end
            else
              k := 0;
            writeln();
          end
        else
          begin
            write(i, ' ');
            k := k + 1;
          end
        else if(k > L) then  //условие для уменьшения
          begin
            write(i, ' ');
            k := k - 1;
            if((k = L) and ((k <= 1) or (L <= 1))) then //условие на выход из уменьшения, далее елка увеличивается
              begin
                l := 2;  // создаем стартовые условия для увеличения
                k := 0;
                writeln();
              end
            else if(k = L) then //уменьшаем длину строки на 1 и переход на строку 34
              begin
                L := L - 1;  // создается разница в 2 раза между L и k
                k := L * 2;
                writeln();
              end;
          end;
      i := i + 1;
    end;
  readln();
end.    
vedro-compota's picture

1) форматирование
2) переменные одни и те же должны быть записаны в одном регистре
3) проверить комментарии
4) комментарии ко всем переменным

_____________
матфак вгу и остальная классика =)

var N, M, i ,L ,k :integer;
begin
  writeln('vvedi massu elki N ');
  readln(N);
  writeln('vvedi shiriny M ');
  readln(M);
//M - высота елки
//N - всего чисел
  L := 2; // ограничитель символов в строке     (начать с 2х и закончить 1)
  k := 0; //  посимвольный счетчик на строке
  i := 2; // cтартовое числ(начало посроения)
  writeln(1); // верхушка елки(отрисовка в любом случае 1 раз)
  while (i <= N) do //строим елку пока не закончатся цифры
    begin
      if(k <= L) then // условие для входа в код по увеличению елки
        if(k = L) then  //условие когда закончится отрисовка строки
          begin
            i := i - 1;  //уменьшаем текущее число чтобы начать новую строку с нужным(если этого не сделать - будет пропуск)
            L := L + 1;  //увеличиваем длину строки на 1
            if(L > M) then //когда длина строки (L) превышает заданное ограничение на длину строки (М)
              begin
                L := M - 1;   // задаем длину строки на 1 меньшую чем указал пользователь (делается 1 раз после достижения мах)
                k := L * 2;   // создается разница в 2 раза между L и k для спуска обратно(к будет больше в 2 раза и пойдет отсчет обратно т.е к-1 а не к+1)
              end
            else
              k := 0; // обнуляем счетчик для отрисовки новой строки
            writeln(); // переход на эту новую строку
          end
        else // иначе пока есть куда отрисовывать строку
          begin
            write(i, ' '); // Отрисовываем символ в строке
            k := k + 1;    // Изменяем счетчик отрисованного символа в строке
          end
      else  // иначе начинаем уменьшать елку
        begin
          write(i, ' '); // Отрисовываем символ в строке
          k := k - 1;    // уменьшаем (К) т.к он больше ограничителя символов в строке(L) в 2 раза и строка удет на убывание
          if((k <= 1) or (L <= 1)) then //условие на выход из уменьшения когда будет строка из одного символа(создадутся условия для начала увеличения)
            begin
              L := 2;  // создаем стартовые условия для увеличения (Мах длина начнется с 2х символов т.к 1 уже отрисован)
              k := 0;  // создаем стартовые условия для увеличения  (от 0 до L)
              writeln();
            end
          else if(k = L) then //условие когда (К) уменьшилось до (L) и нужно начать отрисовывать новую строку
            begin
              L := L - 1;  // уменьшаем длину строки
              k := L * 2; // создается разница в 2 раза между L и k для
              writeln();
            end;
        end;
      i := i + 1;
    end;
  readln();
end.  
vedro-compota's picture

1)

if(k <= L) then // условие для входа в код по увеличению елки

не очень ясный комментарий
-- на самом деле условие для дальнейшего уменьшения длины строки это:

k = M

или

k = L = M

2) k := L * 2; -- усложнение.

3) Печать числа на каждой итерации, без условий

_____________
матфак вгу и остальная классика =)

var N, M, i ,c ,k :integer;
    f: boolean;

begin
  writeln('vvedi massu elki N ');
  readln(N);
  writeln('vvedi shiriny M ');
  readln(M);
  k := 0;
  c := 1;
  f := true;
  for i := 1 to N do
    begin
      write(i, ' ');
      k := k + 1;

      if((k = c) and (f = true)) then
        begin
          k := 0;
          c := c + 1;
          writeln();
        end
      else if((k = c) and (f = false)) then
        begin
          k := 0;
          c := c - 1;
          writeln();
        end;

      if((c > M) and (f = true)) then
        begin
          f := false;
          c := c - 2;
        end
      else if((c = 1) and (f = false)) then
        f := true
      else if((c < 1) and (f = false)) then   // на случай если высота елки 2
        c := 2;
    end;
  readln();
end. 
vedro-compota's picture


      if((k = c) and (f = true)) then
        begin
          k := 0;
          c := c + 1;
          writeln();
        end
      else if((k = c) and (f = false)) then
        begin
          k := 0;
          c := c - 1;
          writeln();
        end;

-- переписать оптимальнее (перейти на вложенные блоки)
-- условно засчитана, решаем: http://fkn.ktu10.com/?q=node/12724

_____________
матфак вгу и остальная классика =)