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

Урок 15

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

Для N = 6, k=2:

20221

длина=41
Для N = 10, k=2:

2022110012

длина=3
Для N = 15, k=3:

20223300230321

длина=40
Для N = 7, k=2:

010002

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

type
    ArrOfInt = array[1..100] of integer;
пример массива 0 0 3 1 3 0 0 1 0 3 2 2 0 2 2 3 3 3 1 1 1 3 1 2 0
type ArrOfInt = array[1..25] of integer;
var k: integer;
    a: ArrOfInt;

procedure printArray(a1: ArrOfInt); //п-а печати массива
  var i1: integer;

  begin
    writeln('Длина массива: ', length(a1));
    for i1 := low(a1) to high(a1) do
      write(a1[i1], ' ');
  end;

function f1(k1: integer; a1: ArrOfInt): ArrOfInt; // ф-я создаем массив
  var i1: integer;

  begin
    randomize();
    for i1 := low(a1) to high(a1) do //создаем массив и наполняем его
      a1[i1] := random(k1 + 1);
    result := a1;
  end;

function f2(k1: integer; a1: ArrOfInt): boolean; //ф-я проверки, что есть все числа
  var i1, j1: integer;
      s: boolean;

  begin
    s := false;
    for i1 := 0 to k1 do
    begin
      s := false;
      for j1 := low(a1) to high(a1) do
        if i1 = a1[j1] then
        begin
          s := true;
          break;
        end;
      if s = false then
        break;
    end;
    result := s;
  end;

function f3(k1: integer; a1: ArrOfInt): integer; //ф-я индекса отрезков
  var i1, j1, y1, c1{счетчик}, m1{начало отрезка}, p1{конец отрезка}, m2, p2, dif1, dif2: integer;


  begin
    c1 := 0;
    dif1 := 100;
    dif2 := 100;
    m1 := high(a1);
    p1 := low(a1);

  for y1 := low(a1) to (high(a1) - k) do //первый цикл
  begin
    m1 := high(a1);
    p1 := low(a1);
    dif2 := 100;
    for i1 := 0 to k1 do //второй цикл
    begin
    for j1 := y1 to high(a1) do //третий цикл
      begin
        if (i1 = a1[j1]) and (j1 <= m1) then
        begin
          m1 := j1;
          inc(c1);
         if (i1 = a1[j1]) and (j1 >= p1) then
         begin
           p1 := j1;
           inc(c1);
         end;
         break;
        end;
        if (i1 = a1[j1]) and (j1 >= p1) then
        begin
          p1 := j1;
          inc(c1);
        break;
        end
        else if (i1 = (a1[j1])) then
        begin
          inc(c1);
          break;
        end;
        end;
      end;
    if c1 = k1 + 2 then
      dif2 := p1 - m1 + 1;
    c1 := 0;
    if dif2 < dif1 then
    begin
      dif1 := dif2;
      m2 := m1;
      p2 := p1;
    end;
  end;
    result := dif1;
  end;

  begin
    randomize();
    k := random(10) + 1;
    writeln('Новое значение k = ',k);
    a := f1(k, a);
    printArray(a);
    writeln();
    writeln('Все значения встречаются: ', (f2(k, a)));
    if (f2(k, a)) then
      write('На отрезке размером: ',f3(k, a));
    readln();
  end.

КОНСОЛЬ

Новое значение k = 5
Длина массива: 25
2 5 2 0 2 2 3 4 3 5 4 5 0 2 1 0 4 1 1 0 5 2 0 0 1
Все значения встречаются: TRUE
На отрезке размером: 7

Key Words for FKN + antitotal forum (CS VSU):

vedro-compota's picture

добавить решение с переиспользованием фукции из задачи 15 http://fkn.ktu10.com/?q=node/14144

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

type ArrOfInt = array[1..25] of integer;
var k: integer;
    a: ArrOfInt;

procedure printArray(a1: ArrOfInt); //п-а печати массива
  var i1: integer;

  begin
    writeln('Длина массива: ', length(a1));
    for i1 := low(a1) to high(a1) do
      write(a1[i1], ' ');
  end;

function f1(k1: integer; a1: ArrOfInt): ArrOfInt; // ф-я создаем массив
  var i1: integer;

  begin
    randomize();
    for i1 := low(a1) to high(a1) do //создаем массив и наполняем его
      a1[i1] := random(k1 + 1);
    result := a1;
  end;

function f2(k1, m1, p1: integer; a1: ArrOfInt): boolean; //ф-я проверки, что есть все числа на отрезке
  var i1, j1: integer;
      s: boolean;

  begin
    s := false;
    for i1 := 0 to k1 do
    begin
      s := false;
      for j1 := m1 to p1 do
        if i1 = a1[j1] then
        begin
          s := true;
          break;
        end;
      if s = false then
        break;
    end;
    result := s;
  end;

function f3(k1: integer; a1: ArrOfInt): integer; //ф-я получения размера отрезка
  var i1, j1, m1, p1, m2, p2: integer;
 //отладочная b1: boolean;

  begin
    p1 := k1 - 1;
    for i1 := low(a1) to high(a1) do
    begin
      m1 := low(a1) - 1;
      inc(p1);
      m2 := m1;
      p2 := p1;

      for j1 := low(a1) to (high(a1) - (p1 - m1)) do
        begin
          inc(p2);
          inc(m2);
        // отладочная  b1 := f2(k1, m2, p2, a1);
         //отладочная строка writeln('i1 ', i1, ' j1 ', j1, ' m1 ', m1, ' p1 ', p1, ' m2 ', m2, ' p2 ', p2, ' f2 ', b1);
          if f2(k1, m2, p2, a1) then
            break;
        end;
        if f2(k1, m2, p2, a1) then
          break;
    end;
  result := p2 - m2 + 1;
  end;

function f4(k1: integer; a1: ArrOfInt): boolean; //ф-я проверки, что в массиве есть полный набор чисел
  var i1, j1: integer;
      s: boolean;

  begin
    s := false;
    for i1 := 0 to k1 do
    begin
      s := false;
      for j1 := low(a1) to high(a1) do
        if i1 = a1[j1] then
        begin
          s := true;
          break;
        end;
      if s = false then
        break;
    end;
    result := s;
  end;

  begin
    randomize();
    k := random(10) + 1;
    writeln('Новое значение k = ',k);
    a := f1(k, a);
    printArray(a);
    writeln();
    writeln('Все значения встречаются: ', (f4(k, a)));
    if f4(k, a) then
      writeln('На отрезке размером: ',f3(k, a));
    readln();
  end.

КОНСОЛЬ

Новое значение k = 7
Длина массива: 25
5 5 6 0 7 5 0 2 4 7 0 2 3 1 1 6 7 2 2 2 6 7 3 3 1
Все значения встречаются: TRUE
На отрезке размером: 11
vedro-compota's picture

засчитано

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