Задача 16 Урок 15

Задача 16 Урок 15

Дан массив длиной N (не более 100 элементов), состоящий из случайно выбранных чисел из диапазона от 0 до k, где 0≤k Найдите в этом массиве длину самого короткого фрагмента, который содержит все числа от от 0 до k.
Например:

Для быстрой проверки кода через запуск используйте следующий тип массива:

type
    ArrOfInt = array[1..100] of integer;
type inArr = array[1..20] of Integer;
var  a: array [1..20] of integer;
     i, k, N,  min, max: integer;
    res: integer;

function SS(k: integer; a :inarr): integer;    // принимает числа поиска и массив а. 
var t, m, z, q: integer; // счетчик поиска чисел
    flag: boolean;   // тру если элемент найден
begin
  writeln();
  m := 1; // смещение сектора Z враво при каждой итерации
  z := 2;// длина сектора которая будет отражена
  repeat
    for m := 1 to N -(m + z - 1) do  // цикл по смещению сектора слева направо. N -(m + z - 1) - чтобы сектор не вышел за пределы массива
      begin
        q := 0; // счетчик нахождления совпадений в секторе
        for t := 0 to k do   // перебор чисел которые нужно найти(задается пользователем)
          begin
            for i := m to m + z do // проход по сетору. z - увеличивает его если ничего не найдено
              begin
                if(t = a[i]) then // если искомое число найдено в массиве
                  begin
                    flag := true; //элемент найден
                    q := q + 1; //  счетчик совпадений в заданом диапазоне
                    break;        //выход для проверки следующего числа в этом же секторе
                  end
                else
                  flag := false; // число не найдено, сдвинуть сектор вправо на 1
              end;
            if(flag = false) then //если хоть раз вернулся фолс то функция вернет фолс
              break; //выйти и увеличить размер сектора
          end;
          if(q = k + 1) then  //если счетчик всё нашел
            begin
              result := z + 1;  //функция вернуть результат
              break;
            end;
      end;
    m := 1;   // возвращаем сектор влево
    if(z = N) then // если сектор больше массива
      begin
        result := 0;
        break;
      end;
    z := z + 1; // увеличиваем длину сектора
  until(q = k + 1); // закончить тк результат возвращен
  writeln();
end;

begin
writeln('vvedi chislo k(max) chislo dlya zapolneniya');
  readln(k);
  min := 0;
  max := k;
  randomize();
  for i := 1 to 20 do
    begin
      a[i] := random(max - min + 1) + min;
      N := i;
      write(a[i], ' ');
    end;
  writeln();
  if((k >= 0) and (k < N)) then
    begin
      res := SS(k,a);
      if(res <> 0) then
        writeln('samiy korotkiy fragment', res)
      else
        writeln('not found');
    end
  else
      writeln('ERRORR- k vne diapazona');
  readln();
end.   
vvedi chislo k(max) chislo dlya zapolneniya
2

0 0 0 1 2 2 0 0 1 0 0 1 2 2 0 1 1 1 2 2

samiy korotkiy fragment3
vvedi chislo k(max) chislo dlya zapolneniya
4

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

samiy korotkiy fragment6
vedro-compota's picture

функция которая проверяет, что на указанном отрезке есть все числа, должна фигурировать отдельно

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

type inArr = array[1..20] of Integer;
var a: array [1..20] of integer;
    i, k, N,  min, max: integer;
    res: integer;

function CheckNum(k, m, z: integer; a :inarr): integer; //проверка присутствия всех чисел в секторе
var t, q: integer; // счетчик поиска чисел
    flag: boolean;   // тру если элемент найден
begin
  q := 0; // счетчик нахождления совпадений в секторе
  for t := 0 to k do   // перебор чисел которые нужно найти(задается пользователем)
    begin
      for i := m to m + z do // проход по сетору. z - увеличивает его если ничего не найдено
        begin
          if(t = a[i]) then // если искомое число найдено в массиве
            begin
              flag := true; //элемент найден
              q := q + 1; //  счетчик совпадений в заданом диапазоне
              break;        //выход для проверки следующего числа в этом же секторе
            end
          else
              flag := false; // число не найдено, сдвинуть сектор вправо на 1
        end;
      if(flag = false) then //если хоть раз вернулся фолс то функция вернет фолс
        break; //выйти и увеличить размер сектора
    end;
  result := q;
end;


function CountFragment(k: integer; a :inarr): integer;    // проверка на наличие сектора со всеми числами (возврат его размера )
var  m, z, q: integer; // счетчик поиска чисел
begin
  writeln();
  m := 1; // смещение сектора Z враво при каждой итерации
  z := 1;// длина сектора проверки (которая будет возвращена как результат
  repeat
    for m := 1 to N -(m + z - 1) do  // цикл по смещению сектора слева направо. N -(m + z - 1) - чтобы сектор не вышел за пределы массива
      begin
        q := CheckNum(k, m, z, a);
        if(q = k + 1) then  //если счетчик всё нашел
          begin
            result := z + 1;  //функция вернуть результат
            break;
          end;
      end;
    m := 1;   // возвращаем сектор влево для начала новой проверки 
    if(z = N) then // если сектор больше массива (т.е фрагмет не найден никакой длины)
      begin
        result := 0;
        break;
      end;
    z := z + 1; // увеличиваем длину сектора
  until(q = k + 1); // закончить тк результат возвращен
  writeln();
end;

begin
  writeln('vvedi chislo k(max) chislo dlya zapolneniya');
  readln(k);
  min := 0;
  max := k;
  randomize();
  for i := 1 to 20 do
    begin
      a[i] := random(max - min + 1) + min;
      N := i;
      write(a[i], ' ');
    end;
  writeln();
  if((k >= 0) and (k < N)) then
    begin
      res := CountFragment(k,a);
      if(res <> 0) then
        writeln('samiy korotkiy fragment', res)
      else
        writeln('not found');
    end
  else
      writeln('ERRORR- k vne diapazona');
  readln();
end.                                            
vedro-compota's picture

function CheckNum(k, m, z: integer; a :inarr): integer;

-- функция должна возвращать boolean

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

type inArr = array[1..20] of Integer;
var a: array [1..20] of integer;
    i, k, N,  min, max: integer;
    res: integer;

function CheckNum(k, m, z: integer; a :inarr): boolean; //проверка присутствия всех чисел в секторе
var t, q: integer; // счетчик поиска чисел
    flag: boolean;   // тру если элемент найден
begin
  q := 0; // счетчик нахождления совпадений в секторе
  for t := 0 to k do   // перебор чисел которые нужно найти(задается пользователем)
    begin
      for i := m to m + z do // проход по сетору. z - увеличивает его если ничего не найдено
        begin
          if(t = a[i]) then // если искомое число найдено в массиве
            begin
              flag := true; //элемент найден
              q := q + 1; //  счетчик совпадений в заданом диапазоне
              break;        //выход для проверки следующего числа в этом же секторе
            end
          else
            flag := false; // число не найдено, сдвинуть сектор вправо на 1
        end;
      if(flag = false) then //если хоть раз вернулся фолс то функция вернет фолс
        break; //выйти и увеличить размер сектора
    end;
  if(q = k + 1) then
    result := true
  else
    result := false;
end;


function CountFragment(k: integer; a :inarr): integer;    // проверка на наличие сектора со всеми числами (возврат его размера )
var  m, z: integer; // счетчик поиска чисел
    flag: boolean;
begin
  flag:= false;
  writeln();
  m := 1; // смещение сектора Z враво при каждой итерации
  z := 1;// длина сектора проверки (которая будет возвращена как результат
  repeat
    for m := 1 to N -(m + z - 1) do  // цикл по смещению сектора слева направо. N -(m + z - 1) - чтобы сектор не вышел за пределы массива
      begin
        if(CheckNum(k, m, z, a)) then  //если счетчик всё нашел
          begin
            flag:= true;
            result := z + 1;  //функция вернуть результат
            break;
          end;
      end;
    m := 1;   // возвращаем сектор влево для начала новой проверки
    if(z = N) then // если сектор больше массива (т.е фрагмет не найден никакой длины)
      begin
        result := 0;
        break;
      end;
    z := z + 1; // увеличиваем длину сектора
  until(flag); // закончить тк результат возвращен
  writeln();
end;

begin
  writeln('vvedi chislo k(max) chislo dlya zapolneniya');
  readln(k);
  min := 0;
  max := k;
  randomize();
  for i := 1 to 20 do
    begin
      a[i] := random(max - min + 1) + min;
      N := i;
      write(a[i], ' ');
    end;
  writeln();
  if((k >= 0) and (k < N)) then
    begin
      res := CountFragment(k,a);
      if(res <> 0) then
        writeln('samiy korotkiy fragment ', res)
      else
        writeln('not found');
    end
  else
      writeln('ERRORR- k vne diapazona');
  readln();
end. 
vedro-compota's picture

решение засчитано

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