| Россия, Пошатово |
Переменные, выражения, присваивания
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)
). Найти одно из таких чисел х.Решение. Введем массив
,
отмечающий начало "остающейся части" массивов
.
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.
Указание. Придется пожертвовать симметрией и выбрать одну из строк за основную. Двигаясь по основной строке, поддерживаем такое соотношение: во всех остальных строках отмечен максимальный элемент, не превосходящий текущего элемента основной строки.