Root /ArchiveAbout
()

Количество возрастающих, убывающих, пилообразных наборов

Количество возрастающих, убывающих, пилообразных наборов

Здравствуйте, постоянные читатели моего сайта о программировании для начинающих! На этой странице займемься решением последней группы задач Series35-40 задачника Абрамяна, посвященных последовательностям без использования массивов. Во всех задачах, как и на странице Series12-16, набор чисел оканчивается при вводе 0.

Series35. Дано целое число K, а также K наборов ненулевых целых чисел. Признаком завершения каждого набора является число 0. Для каждого набора вывести количество его элементов. Вывести также общее количество элементов во всех наборах.

Обозначим через Q общее количество элементов во всех наборах, а через count – количество элементов каждого набора. Естественно, чтобы получить количество всех элементов, необходимо сложить элементы во всех наборах. Последовательность действий по строках кода будет следующая:

var
  a, Q, count: integer;
  K, i: byte;

begin
  write('K = ');
  readln(K);
  Q := 0; { <== общее количество элементов }
  for i := 1 to K do begin
    writeln;
    writeln('Вводим числа ', i, '-го набора:');
    count := 0; { <== количество элементов i-го набора }
    repeat
      read(a); { <-- вводим число }
      inc(count) { <== увеличиваем количество на 1 }
    until a = 0;
    writeln('--> ', count);
    Q := Q + count { <== Увеличиваем общее число элементов }
  end;
  writeln('Общее число элементов = ', Q);
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255 **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1 Series36. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее двух элементов, признаком его завершения является число 0. Найти количество наборов, элементы которых возрастают.

В условии ничего не сказано о том, нужно ли при проверке чисел на возрастание учитывать последнее число 0 или нет. Так, последовательность чисел 1 2 3 4 5 0 не является возрастающей, если учитывать 0; но если 0 не брать во внимание, то данный набор элементов – возрастающий. Поэтому будем писать программу для случая, если 0 не входит в состав монотонно возрастающих элементов. Поскольку в данном случае 0 – это всего лишь сигнал о прекращении набора данных.

Зато в условии говорится, что последовательность должна иметь как минимум 2 элемента. Этого можно достичь простым способом – просто перед заходом в цикл вводить 2 элемента, а все остальные – в цикле, где и будем определять, монотонная последовательность или нет (монотонная – это собирательное название для возрастающих или убывающих последовательностей).

Чтобы сообщить, возрастают числа в наборе при вводе или нет, введем логическую переменную bln (от "boolean"), которая будет принимать значение True, если последовательность возрастает, и False в противном случае.

✎ Возрастающая последовательность — это последовательность чисел, где каждое последующее число, кроме первого, больше предыдущего; то есть все элементы больше своего левого соседа.

Поэтому мы будем действовать таким образом: если мы ввели какое-то количество чисел, и все они к моменту ввода последнего числа только возрастали, то при вводе следующего числа имеет смысл проверять, больше оно своего предыдущего соседа или нет. То есть, если bln=true, то делаем проверку, если bln=False, то проверять не надо, так как последовательность чисел в наборе уже нарушена.

Делается это по следующиму принципу. Пусть мы хотим ввести набор элементов 10 20 30 1 0. Как видим он не возрастающий. Сначала ставим перед в заходом во внутренний цикл bln:=true (строка 10 кода); это означает, что по умолчанию мы считаем последовательность возрастающей. Вводим два первых элемента: 10 — назовем его предыдущим (PreElem), и 20 (текущее число а). Поскольку 20>10, то величина bln не изменится и будет равна true, и сразу после этого предыдущий элемент меняем на текущий: PreElem:=a (строка 18 кода), а после проверки вводим слудующий элемент 30. Далее, 30>20, поэтому bln тоже не изменится и равно true. Но со вводом элемента 1 мы получим bln=false, поскольку 1<30, поэтому подсчет количества возрастающих наборов в строке 22 не сработает.

Из обозначений: Q — количество наборов с возрастающими элементами, a — число для ввода, PreElem — обозначает предыдущий элемент. Все остальные комментарии к программе в коде, если что не понятно — задавайте вопросы в комментариях.

var
  a, PreElem, Q, K, i: integer; { a - вводимое число, PreElem - предыдущее число }
  bln: boolean; { true - набор возрастает, false - не возрастает  }

begin
  write('K = '); readln(K); { <-- Вводим K }
  Q := 0; { <== количество наборов с возрастающими элементами }
  for i := 1 to K do begin
    writeln('Вводим числа ', i, '-го набора:');
    bln := true; { <-- по умолчанию числа возрастают }
    read(PreElem); { <-- первое число }
    repeat
      read(a); { <-- вводим следующее число }
      if bln then { <-- проверять имеет смысл только в том случае, если 
       последовательность до ввода а была возрастающей, bln=True }
        { если элемент а больше предыдущего PreElem, то 
        предыдущий сдвигаем на позицию вправо: }
        if (a > PreElem) then PreElem := a
        else bln := false { иначе сообщаем, что набор - не возрастающий }
    until a = 0;
    { Если набор возрастающий, то увеличиваем количество Q на 1: }
    if bln then inc(Q)
  end;
  writeln('Количество возрастающих наборов = ', Q);
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** boolean;: Представляет логическое значение. **const** true = True;: Представляет логическое значение. **const** false = False;: Представляет логическое значение. **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1 Series37. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее двух элементов, признаком его завершения является число 0. Найти количество наборов, элементы которых возрастают или убывают.

Комментарии в коде прораммы.

var
  a, PreElem, Q, K, i, p: integer; { PreElem - первое, a - второе число }

begin
  readln(K); { <-- Вводим K }
  Q := 0; { <== количество наборов с возрастающими элементами }
  for i := 1 to K do begin
    writeln('Вводим числа ', i, '-го набора:');
    read(PreElem); { <-- первое число }
    read(a); { <-- второе число }
    if a < PreElem then p := -1 { <-- элементы убывают }
    else
      if a > PreElem then p := 1 { <-- элементы возрастают }
      else p := 0; { <-- элементы совпадают, p = 0 }
    while a <> 0 do begin
      if p <> 0 then { <-- монотонность не нарушена }
       { Если последовательность:
          убывала (p=-1) и продолжает убывать (a<PreElem), ИЛИ
          возрастала (p=1) и продолжает возрастать (a>PreElem), 
          то на месте второго числа ставим первое: }
        if (p=-1)and(a<PreElem) or (p=1)and(a>PreElem) then PreElem := a
        else p := 0; { <-- если же в последовательности 
          нарушена монотонность, то меняем индикатор p }
      read(a) { <-- вводим второе число }
    end;
    { На выходе из цикла (после ввода числа 0), если набор 
    монотонный, то увеличиваем количество Q на 1: }
    if (p=-1)or(p=1) then inc(Q)
  end;
  writeln('Количество монотонных наборов = ', Q);
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1 Series38. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее двух элементов, признаком его завершения является число 0. Для каждого набора выполнить следующее действие: если элементы набора возрастают, то вывести 1; если элементы набора убывают, то вывести −1; если элементы набора не возрастают и не убывают, то вывести 0.

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

var
  a, PreElem, K, i, p: integer; { PreElem - первое, a - второе число }

begin
  readln(K); { <-- Вводим K }
  for i := 1 to K do begin
    writeln('Вводим числа ', i, '-го набора:');
    read(PreElem); { <-- первое число }
    read(a); { <-- второе число }
    if a < PreElem then p := -1 { <-- элементы убывают }
    else
      if a > PreElem then p := 1 { <-- элементы возрастают }
      else p := 0; { <-- элементы совпадают, p = 0 }
    while a <> 0 do begin
      if p <> 0 then { <-- монотонность не нарушена }
       { Если последовательность:
          убывала (p=-1) и продолжает убывать (a<PreElem), ИЛИ
          возрастала (p=1) и продолжает возрастать (a>PreElem), 
          то на месте второго числа ставим первое: }
        if (p=-1)and(a<PreElem) or (p=1)and(a>PreElem) then PreElem := a
        else p := 0; { <-- если же в последовательности 
          нарушена монотонность, то меняем индикатор p }
      read(a) { <-- вводим второе число }
    end;
    { Если набор элементов не нарушил начальную направленность, то есть 
    постоянно возрастал или убывал (p=1 или p=-1 соответственно), то 
    после выхода из цикла p не изменит своего значения, иначе будет p=0. }
    writeln(p)
  end;
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 Series39. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее трех элементов, признаком его завершения является число 0. Найти количество пилообразных наборов (определение пилообразного набора дано в задании Series23).

Здесь для ввода первых трех элементов используем переменные а1, а2, а3. Но при необходимости количество переменных можно уменьшить до 2, то есть рассматривать только первые два числа а1 и а2. Сначала посмотрите задачу Series23. Все комментарии в коде программы.

var
  a1, a2, a3, K, i, p, Q: integer;

begin
  write('K = '); readln(K); { <-- Вводим K }
  for i := 1 to K do begin
    writeln('Введите элементы набора №', i, ':');
    read(a1); { <-- первое число }
    read(a2); { <-- второе число }
    read(a3); { <-- третье число }
    { Если второй элемент а2 из первых трех членов набора является
    локальным максимумом (больше своих левого и правого соседей), 
    то ставим p=1, если локальным минимумом (меньше своих соседей),
    то p=-1, иначе (последовательность монотонная, строгая или не 
    строгая) ставим p=0: }
    if (a1<a2)and(a2>a3) then p := 1 { <-- локальный максимум }
    else
      if (a1>a2)and(a2<a3) then p := -1 { <-- локальный минимум }
      else p := 0;
    while a3 <> 0 do begin
      p := -p; { <-- Если мы имели локальный максимум, то следующим 
      должен быть локальный минимум, поэтому 1 меняем на -1, и наоборот }
      if p <> 0 then { <-- Имеет смысл проверять элементы, если 
       набор до момента ввода последнего числа был пилообразным }
        if (p = -1)and(a2 > a3) or 
         (p = 1)and(a2 < a3) then a2 := a3 { <-- третье число стает вторым }
        else p := 0; { <-- "пилообразность" набора нарушается, p = 0 }
      read(a3) { <-- вводим третье число }
    end;
    if p <> 0 then inc(Q) { <-- если набор пилообразный, то увеличиваем 
    количество таких наборов на 1 }
  end;
  writeln('Количество пилообразных наборов: ', Q);
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1 Series40. Дано целое число K, а также K наборов ненулевых целых чисел. Каждый набор содержит не менее трех элементов, признаком его завершения является число 0. Для каждого набора выполнить следующее действие: если набор является пилообразным (см. задание Series23), то вывести количество его элементов; в противном случае вывести номер первого элемента, который не является зубцом.

В нижеприведенном коде последнее число набора 0 при определении локальности учитывается.

var
  a1, a2, K, i, p, Q: integer;

begin
  write('K = '); readln(K); { <-- Вводим K }
  for i := 1 to K do begin
    writeln('Введите элементы набора №', i, ':');
    read(a1); { <-- первое число }
    read(a2); { <-- второе число }
    Q := 2; { <== начальное количество элементов }
    if (a1 < a2) then p := 1 { <-- локальный максимум }
    else
      if (a1 > a2) then p := -1 { <-- локальный минимум }
      else p := 0; { <== пилообразность набора нарушается, a1=a2 }
    a1 := a2; { <== второе число стает первым }
    repeat
      read(a2); { <-- вводим новое второе число }
      if p <> 0 then begin
        p := -p; { <== следующий локальный элемент a2
          должен быть противоположного типа }
        inc(Q);
        if (p=-1)and(a1>a2) or (p=1)and(a1<a2) then a1 := a2
        else p := 0 { <== пилообразность набора нарушается }
      end
    until a2 = 0; { <-- выходим при вводе 0 }
    if p <> 0 then writeln('Количество пилообразных элементов: ', Q)
    else writeln('Номер элемента нарушающий пилообразность: ', Q)
  end;
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1 Также рекомендую посмотреть материал о локальных минимумах и локальных максимумах, только с использованием массивов. Вобщем, если что ещё не понятно, то можете прокомментировать, или напишите какое-то свое решение, поделитесь мыслями, может быть, я что-то упустил.