Разбор решения. Урок 15 Задача 20 - Поиск элементов в массиве, минимальный отрезок
Primary tabs
Условие:
Дан массив длиной N (не более 100 элементов), состоящий из случайно выбранных чисел из диапазона от 0 до k, где 0≤k
Например:
-
Для N = 6, k=2:
$ 2\; \underbrace{0\; 2 \;2 \;1}_{\text{длина=4}}\; 1 $ -
Для N = 10, k=2:
$ 2\; 0\; 2\; 2\; 1\; 1\; 0\; \underbrace{0\; 1\; 2}_{\text{длина=3}} $ -
Для N = 15, k=3:
$ 2\; 0\; 2\; 2\; 3\; 3\; 0\; 0\; 2 \; 3 \; \underbrace{0 \; 3 \; 2 \; 1}_{\text{длина=4}} \; 0 $ -
Для N = 7, k=2:
$ 0\; \underbrace{ 1 \;0 \;0 \;0 \;2}_{\text{длина=5}}\; 0 $
Решение:
type Arr= array[1..10] of integer; //Объявим тип: массив из десяти чисел. var bigArr: Arr; k,i,min,l,m: integer; // Объявим переменные.
Здесь:
-
i
- счётчик, определяющий порядковый номер элемента массива bigArr в цикле. min
- понадобится для заполнения массива случайными числами с помощью randomize. В этом примере для удобства проверки массив задаётся вручную, так что она не используется.l
- результат сравнения текущего значения m с предыдущим: наименьший из рассмотренных участок массива, на котором встречаются все числа промежутка [0,k]. Начальное значение = длина массива+1, сохранится, только если в массиве встречаются не все числа промежутка [0,k].m
- результат выполнения функции otrezok: участок массива, на котором встречаются все числа промежутка [0,k].
Тело программы:
type Arr= array[1..10] of integer; var bigArr: Arr; k,i,min,l,m: integer; function otrezok (b:Arr; first,d:integer):integer; {функцию рассмотрим ниже} begin k:=3; l:=11; //Здесь массив из 10 чисел, задаём такое значение, чтоб l //точно уменьшилась в процессе bigArr[1]:= 2; //Для удобства проверки задаём массив вручную bigArr[2]:= 1; bigArr[3]:= 0; bigArr[4]:= 2; bigArr[5]:= 1; bigArr[6]:= 0; bigArr[7]:= 0; bigArr[8]:= 2; bigArr[9]:= 1; bigArr[10]:= 3; for i:=low(bigArr) to (high(bigArr)-k) do {Верхняя граница = high(bigArr)-k, так как функция будет искать числа [0,k] начиная с i-того элемента, нет смысла искать числа от 0 до k на участке меньше k.} begin m:= otrezok(bigArr,i,k); {В функцию передаётся массив, порядковый номер элемента, с которого функция начнёт поиск чисел [0,k] и само число k.} {Для удобства результат выполнения функции присваивается переменной m.} if m=0 then {Если m=0, значит, найдены не все числа промежутка [0,k]} break; //дальнейшее прохождение цикла лишается смысла if m <l then {значение m сравнивается со значением l, и если этот участок (m) короче предыдущего (l), переменной l присваивается новое значение m.} l:= m; end; if l=11 then {Если в массиве есть все числа [0,k], l уменьшится хотя бы на единицу} write ('net takogo uchastka') else write ('Otvet: ', l); readln(); end.
Кратчайший участок массива с числами [0,k] находится через сравнение результатов функции.
Функция
Задача функции otrezok - найти в массиве bigArr участок, где встречаются все числа от нуля до k.
Для этого функция будет сравнивать поочерёдно числа от 0 до k с каждым элементом массива bigArr начиная с первого элемента.
Функция принимает аргумент i за точку отсчёта, то есть ищет все числа промежутка [0,k], начиная с i-того элемента массива. То есть, извне передаётся i=1 - ищет числа [0,k] во всём массиве, пока не найдёт k или не переберёт все элементы массива. Потом i=2 - поиск начинается со второго элемента, потом с третьего и так далее.
Функция находит все ближайшие к точке отсчёта числа до k и возвращает расстояние от точки отсчёта до самого дальнего из ближайших чисел [0,k].
Если массив пройден, а одно из искомых чисел не найдено, функция вернёт 0.
type Arr= array[1..10] of integer; var bigArr: Arr; k,i,min,l,m: integer; function otrezok(a:Arr; i,k:integer):integer; var h,j,last:integer; begin last:=0; for j:=0 to k do begin for h:= i to high(a) do if a[h]=j then begin if (h-i+1)>last then last:=(h-i+1); //когда найдено числ k, внутренний цикл прерывается if (h= high(a)) and (a[h]<>j) then {массив пройден, а нужное число не обнаружено.} begin last:=0; {Если массив пройден, а одно из искомых чисел не найдено - переменная last обнулится.} break; //Внешний цикл прерывается. end; end; result:=last; end;
Код целиком:
type Arr= array[1..10] of integer; var bigArr: Arr; k,i,min,l,m: integer; function otrezok(a:Arr; i,k:integer):integer; var h,j,last:integer; begin last:=0; for j:=0 to k do begin for h:= i to high(a) do if a[h]=j then begin if (h-i+1)>last then last:=(h-i+1); break; end; if (h= high(a)) and (a[h]<>j) then begin last:=0; break; end; end; result:=last; end; begin k:=3; l:=11; bigArr[1]:= 2; bigArr[2]:= 1; bigArr[3]:= 0; bigArr[4]:= 2; bigArr[5]:= 1; bigArr[6]:= 0; bigArr[7]:= 0; bigArr[8]:= 2; bigArr[9]:= 1; bigArr[10]:= 3; for i:=low(bigArr) to (high(bigArr)-k) do begin m:= otrezok(bigArr,i,k); if m=0 then break; if m <l then l:= m; end; if l=11 then write ('net takogo uchastka') else write ('Otvet: ', l); readln(); end.
- Log in to post comments
- 238 reads
vedro-compota
Sun, 03/23/2025 - 14:51
Permalink
можно отдельно написать
можно отдельно написать заметку о возможности ручного задания массива вместо рэндома и пользовательского вврода на время отладки
_____________
матфак вгу и остальная классика =)