Россия, Пошатово |
Переменные, выражения, присваивания
1.2.20.
Даны два массива
и
. "Соединить" их
в массив
(
; каждый элемент должен входить
в массив z столько раз, сколько раз он входит в общей
сложности в массивы x и y ). Число действий
порядка m.
Решение.
k1 := 0; l1 := 0; {инвариант: ответ получится, если к z[1]..z[k1+l1] добавить справа соединение массивов x[k1+1]..x[k] и y[l1+1]..y[l]} while (k1 <> k) or (l1 <> l) do begin | if k1 = k then begin | | {l1 < l} | | l1 := l1 + 1; | | z[k1+l1] := y[l1]; | end else if l1 = l then begin | | {k1 < k} | | k1 := k1 + 1; | | z[k1+l1] := x[k1]; | end else if x[k1+1] <= y[l1+1] then begin | | k1 := k1 + 1; | | z[k1+l1] := x[k1]; | end else if x[k1+1] >= y[l1+1] then begin | | l1 := l1 + 1; | | z[k1+l1] := y[l1]; | end else begin | | { такого не бывает } | end; end; {k1 = k, l1 = l, массивы соединены}
Этот процесс можно пояснить так. Пусть у нас есть две стопки карточек, отсортированных по алфавиту. Мы соединяем их в одну стопку, выбирая каждый раз ту из верхних карточек обеих стопок, которая идет раньше в алфавитном порядке. Если в одной стопке карточки кончились, берем их из другой стопки.
1.2.21.
Даны два массива
и
. Найти их "
пересечение", то есть массив
содержащий их общие
элементы, причем кратность каждого элемента в массиве z
равняется минимуму из его кратностей в массивах x
и y. Число действий порядка
.
1.2.22.
Даны два массива
и
и число q. Найти сумму
вида
, наиболее близкую к числу q.
(Число действий порядка k+l, дополнительная память -
фиксированное число целых переменных, сами массивы
менять не разрешается.)
Указание.
Надо найти минимальное расстояние между элементами
и
, что нетрудно
сделать в ходе их слияния в один (воображаемый) массив.
1.2.23.
(из книги Д. Гриса) Некоторое число содержится в каждом из
трех целочисленных неубывающих массивов ,
,
. Найти одно из таких чисел.
Число действий должно быть порядка
.
Решение.
p1:=1; q1=1; r1:=1; {инвариант: x[p1]..x[p], y[q1]..y[q], z[r1]..z[r] содержат общий элемент} while not ((x[p1]=y[q1]) and (y[q1]=z[r1])) do begin | if x[p1]<y[q1] then begin | | p1:=p1+1; | end else if y[q1] <z[r1] then begin | | q1:=q1+1; | end else if z[r1] <x[p1] then begin | | r1:=r1+1; | end else begin | | { так не бывает } | end; end; {x[p1] = y[q1] = z[r1]} writeln (x[p1]);
1.2.24. Та же задача, только заранее не известно, существует ли общий элемент в трех неубывающих массивах и требуется это выяснить (и найти один из общих элементов, если они есть).
1.2.25. Элементами массива a[1..n] являются неубывающие массивы [1..m] целых чисел:
![\begin{multiple}
\text{a: array [1..n] \text {of array} [1..m] \text {of integer};}\\
%
\w{a[1][1]}\le\ldots\le\w{a[1][m]},\ldots,
\w{a[n][1]}\le\ldots\le\w{a[n][m]}.
\end{multiple)](/sites/default/files/tex_cache/9f45bec60415c5b89ec7f13277ecbfa0.png)
![a[i][j]=x](/sites/default/files/tex_cache/1393b12aefd70de9f5cecc5936b1de18.png)
Решение. Введем массив ,
отмечающий начало "остающейся части" массивов
.
for k:=1 to n do begin | b[k]:=1; end; eq := true; for k := 2 to n do begin | eq := eq and (a[1][b[1]] = a[k][b[k]]); end; {инвариант: оставшиеся части пересекаются, т.е. существует такое х, что для всякого i из [1..n] найдется j из [1..m], не меньшее b[i], для которого a[i][j] = х; eq <=> первые элементы оставшихся частей равны} while not eq do begin | s := 1; k := 1; | {a[s][b[s]] - минимальное среди a[1][b[1]]..a[k][b[k]]} | while k <> n do begin | | k := k + 1; | | if a[k][b[k]] < a[s][b[s]] then begin | | | s := k; | | end; | end; | {a[s][b[s]] - минимальное среди a[1][b[1]]..a[n][b[n]]} | b [s] := b [s] + 1; | for k := 2 to n do begin | | eq := eq and (a[1][b[1]] = a[k][b[k]]); | end; end; writeln (a[1][b[1]]);
1.2.26.
Приведенное решение предыдущей задачи требует порядка действий. Придумать способ с числом действий
порядка mn.
Указание. Придется пожертвовать симметрией и выбрать одну из строк за основную. Двигаясь по основной строке, поддерживаем такое соотношение: во всех остальных строках отмечен максимальный элемент, не превосходящий текущего элемента основной строки.