Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Гладков_Кулютникова Информатика

.pdf
Скачиваний:
29
Добавлен:
29.03.2015
Размер:
998.19 Кб
Скачать

63 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

then begin max := a[i]; s := 1 end else if max = a[i]

then s := s + 1;

2.В городе N закусочных. Известны расстояния от каждой закусочной до цетра города. Нужно указать пару закусочных, расположенных дальше всего друг от друга, если переходы от закусочной к закусочной осуществляются через центр.

3.Последовательность определяется по следующим правилам: a0 = 9;

ak+1 = 3ak4 + 4ak3 для любого k > 0. Заданы номера элементов этой последовательности i и

j.Определите в записи какого элемента входит больше цифр девять.

4.В одномерном массиве целых чисел найдите максимальный среди элементов, являющихся четными, и минимальный среди элементов, кратных А.

5.Автомат, приклеивающий этикетки, работает со светлыми, зелеными и темными бутылками, в которые наливаются светлые и темные жидкости. Темные бутылки с темной жидкостью автомат разбивает. Сколько бутылок из 1997 штук разобьет автомат? Вид бутылки и жидкости в ней задается случайным числом.

6.В массиве хранятся натуральные числа из интервала от 10 до 50, сформированные случайным образом. Выведите его на экран построчно, где каждая строка содержит столько звездочек, каково значение соответствующего элемента массива.

7.В одномерном массиве хранятся случайные натуральные числа от -10 до 37. Напечатайте содержимое соответствующего элемента массива в виде столбца звездочек вверх (в случае положительного элемента) или вниз (в случае отрицательного элемента) от базовой строки. Например, для А = {-2, 3, 2, -3, 4, -2} получим:

 

1

2

3

4

5

6

начало листа

 

 

 

 

*

 

 

 

*

 

 

*

 

 

 

*

*

 

*

 

 

 

*

*

 

*

 

базовая точка

-

-

-

-

-

-

 

*

 

 

*

 

*

 

*

 

 

*

 

*

 

 

 

 

*

 

 

Задачи второго класса

Особенностью задач этого класса является изменение порядка следования элементов массива. Для этого часто приходится менять местами элементы массива. Поэтому необходимо ввести дополнительную переменную, для того, чтобы не потерять старое значение элемента массива. Это выполняется с помощью приведенных ниже операторов.

Задача 1. Поменяйте местами значения переменных a[i] и a[j].

Решение.

 

r := a[i];

{запомнили a[i] во вспомогательной переменной}

a[i] := a[j];

{ записали значение a[j] на место a[i], старое значение

 

последнего потерялось, но сохранилась его копия в

 

переменной r}

a[j]:=r;

{ записали запомненное значение a[i] на место a[j]}

Задача 2. Переверните массив, т.е. запишите элементы массива в обратном порядке. Решение. Для решения этой задачи необходимо поменять местами первый и последний, второй и предпоследний и т.д. элементы. Этот процесс нужно продолжать до тех пор, пока не дойдем до середины массива, иначе массив будет перевернут дважды и получим исходное расположение элементов. Для решения этой задачи хорошо подходит

схема перебора элементов массива по два при движении с обеих сторон. i := 1; j := n;

64 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

while i <= j do begin

r := a[i]; a[i] := a[j]; a[j] := r;

i := i + 1; j := j +1

end;

Упражнение. Внесите изменения в приведенный выше фрагмент программы для того, чтобы переворачивалась часть массива от элемента с номером p до элемента с номером q, не используя при этом дополнительный массив.

Задача 3. Поменяйте местами пары соседних элементов, т.е. первый и второй, третий и четвертый и т.д. (n-1)-ый и n-ый.

Решение. В этой задаче используется схема обмена элементов при схеме перебора с шагом два.

i := 2;

while i < n do begin

r := a[i];

a[i] := a[i+1]; a[i+1] := r;

i := i + 2

end;

Задача 4. Циклически сдвиньте элементы массива на один элемент влево.

Решение. Циклический сдвиг означает, что происходит следующая замена: первый элемент заменяется вторым, второй - третьим и т.д., последний - старым значением первого. При этом можно потерять только значение первого элемента, которое и необходимо сохранить перед циклом.

r := a[1];

for i := 1 to n-1 do a[i] := a[i + 1];

a[n] := r;

Задача 5. Сдвиньте циклически элементы массива на k позиций влево.

Решение. Можно воспользоваться предыдущим решением, повторив k раз сдвиг на один элемент.

for j := 1 to k do begin

r := a[1];

for i := 1 to n - 1 do a[i] := a[i + 1]; a[n] := r

end.

Можно решить эту задачу с использованием вспомогательного массива, в котором будут сохранены первые k элементов. Затем, после сдвига оставшихся элементов на k позиций влево, в оставшиеся позиции будут переписаны элементы из вспомогательного массива.

for i := 1 to k do b[i] := a[i];

for i := 1 to n - k do a[i] := a[i + k];

for i := n- k + 1 to n do

65 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

a[i] := b[i - k + 1];

Упражнение. Напишите программу циклического сдвига одномерного массива вправо на k элементов.

Задачи третьего класса

Если обрабатываются несколько массивов одновременно, то для каждого массива нужно выбрать подходящую схему перебора, завести свой индекс, следить, чтобы индекс не вышел за границы массива. В некоторых частных случаях для обработки нескольких массивов бывает достаточно одного индекса, потому что элементы массива обрабатываются "синхронно", то есть, зная индекс элемента одного массива, можно вычислить по некоторой формуле индекс соответствующего ему элемента другого массива. Если такой формулы установить не удается, то говорят, что массивы обрабатываются "асинхронно".

Задача 1. Дан массив целых чисел. Необходимо сформировать второй массив, содержащий четные элементы первого массива, при этом расположить элементы во втором массиве а) на тех же позициях, что и в первом; б) сдвинуть к началу массива.

Решение. В первом случае необходимо проверять каждый элемент первого массива на четность, использовав при этом любую из схем перебора по одному. При этом индекс у второго массива меняется таким же образом. Здесь элементы массива обрабатываются синхронно, достаточно одного индекса. Во втором случае массивы обрабатываются асинхронно, необходимо ввести свою переменную для индекса второго массива, которая будет изменять свое значение только в случае записи элемента в массив.

Вариант 1. const nn = 30;

var a, b: array [1..nn] of integer; i, n: integer;

begin

write (‘задайте количество элементов массива’); readln (n);

for i := 1 to n do begin

read (a[i]);

if a[i] mod 2 = 0 then b[i] := a[i];

end;

for i := 1 to n do write (b[i], ‘ ‘);

end.

Вариант 2. const nn = 30;

var a, b: array [1..nn] of integer; i, k, n: integer;

begin

write (‘задайте количество элементов массива’); readln (n);

for i := 1 to n do read (a[i]);

k := 0; {в массиве b нет еще элементов} for i := 1 to n do

if a[i] mod 2 = 0 then begin

k := k + 1;

66 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

b[k] := a[i];

end;

for i := 1 to k do write (b[i], ‘ ‘);

end.

Задача 2. Даны два массива целых чисел a и b. Необходимо получить третий массив

c, для n = 5 следующего вида: a1 b5 a2 b4 a3 b3 a4 b2 a5 b1.

Решение. Элементы массивов обрабатываются асинхронно. Заметим, что на нечетных позициях массива c располагаются элементы массива a в прямом порядке, а на четных позициях - элементы массива b в обратном порядке.

const nn = 30;

var a, b: array [1..nn] of integer; с: array [1.. 2*nn] of integer; i, k, n: integer;

begin

write (‘задайте количество элементов массива’); readln (n);

writeln (‘задайте элементы массива а’); for i := 1 to n do

read (a[i]);

writeln (‘задайте элементы массива b’); for i := 1 to n do

read (b[i]);

for i := 1 to n do begin

c[2*i - 1] := a[i]; c[2*i] := b[n- i + 1]

end;

for i := 1 to 2*n do write (c[i], ‘ ‘);

end.

Задачи четвертого класса

Часто в программировании возникает задача отыскать первый элемент, совпадающий с заданным x. Для решения этой задачи могут быть предложены следующие варианты:

*линейный поиск;

*поиск с барьером;

*двоичный поиск.

Линейный поиск

Алгоритм такого поиска был рассмотрен при решении типовых задач на построение циклических алгоритмов. Напомним, что особенностью такого поиска является две причины прекращения поиска: 1) элемент найден (это программируется с помощью логической переменной) и 2) просмотрены все элементы, но заданный элемент так и не нашли (i > n).

const n = 20; {количество элементов в массиве} var a: array [1..n] of integer; {исходный массив}

i, x: integer; f: boolean;

begin

67 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

write (‘задайте искомый элемент’); readln (x);

writeln (‘задайте элементы массива’);

for i := 1 to n do

 

 

readln (a[i]);

 

 

f := false;

{элемент еще не найден}

i := 1;

 

 

while (i <= n) and not f do

 

if a[i] = x then f := true

{нашли}

else i := i + 1;

 

{переходим к следующему элементу}

if f then writeln (‘нашли элемент с номером ’, i) else writeln (‘такого элемента нет’);

end.

Поиск с барьером

Применяется широко распространенный прием фиктивного элемента, или барьера, расположенного в конце массива. Использование барьера позволяет упростить условие окончания цикла, т.к. заранее ясно, что хотя бы один элемент, равный а, в массиве есть. При этом необходимо увеличить размер массива на 1.

const n = 20; {количество элементов в массиве} var a: array [1..n + 1] of integer; {исходный массив}

i, x: integer; begin

write (‘задайте искомый элемент’); readln (x);

writeln (‘задайте элементы массива’);

for i := 1 to n do

 

readln (a[i]);

 

a[n + 1] := x;

{установлен барьер, равный x, в конец массива}

i := 1;

 

while a[i] <> x do

 

i := i + 1;

{переходим к следующему элементу}

if i <> n + 1 then writeln (‘нашли элемент с номером ’, i) else writeln (‘такого элемента нет’);

end.

Двоичный поиск (поиск элемента в упорядоченном массиве)

Алгоритм двоичного поиска достаточно прост. Делим массив пополам и определяем, в какой из его частей может находиться искомый элемент. Поскольку массив упорядочен, то, сравнивая искомый элемент со средним элементом массива, легко определить интересующую нас половину. Затем выбранную половину опять делим пополам и определяем, в какой половине находится искомый элемент. Этот процесс продолжаем до тех пор, пока не будет найден искомый элемент, либо левая граница нового отрезка не станет больше правой. В последнем случае можно сделать вывод о том, что искомого элемента в массиве нет.

const n = 20; {количество элементов в массиве} var a: array [1..n] of integer; {исходный массив}

i, x, k, m : integer;

left, right, mid: integer; {левая, правая граница и середина отрезка} f: boolean;

begin

write (‘задайте искомый элемент’);

68 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

readln (k);

for i := 1 to n do readln (a[i]);

{упорядочивание массива по возрастанию}

for i := 1 to n - 1 do

 

 

begin

 

 

 

m := i;

 

 

 

for j := i + 1 to n do

 

 

if a[j] < a[m] then m := j;

 

 

x := a[i];

 

 

 

a[i] := a[m]; a[m] := x

 

 

end;

 

 

 

{поиск элемента}

 

 

f := false;

{элемент не найден}

left := 1; right := n;

 

 

repeat

{поиск элемента в части массива от элемента[left] до

 

элемента[rigth]}

 

 

mid := (left + right) div 2;

 

 

if k < a[mid] then right := mid - 1

{элемент в левой части}

else if k > a[mid] then left := mid + 1 {элемент в правой части}

else

f := true;

{нашли}

until f or (left > rigth);

 

 

if f then writeln (‘элемент с номером ’,mid:2, ‘совпадает с искомым ’, k ) else writeln (‘не нашли’);

end.

СОРТИРОВКА МАССИВОВ

Часто удобно иметь данные (особенно, если их много), расположенные в порядке возрастания или убывания. Такое упорядочивание в программировании называется сортировкой. Цель сортировки - облегчить поиск элементов в отсортированном массиве. Как правило, при сортировке выдвигается требование экономии памяти, поэтому сортировка осуществляется без использования вспомогательного массива. Сортировать можно любые данные. Важно только, чтобы их можно было тем или иным способом сравнивать. Существует множество различных алгоритмов сортировки. Одни из них простые, но более медленные, другие - быстрые, но более сложные. Одни сортируют массив каждый раз заново, другие - распознают уже упорядоченные части массива и поэтому работают быстрее. В рамках данного пособия будут рассмотрены следующие алгоритмы сортировки:

*вставки;

*пузырька;

*выбора;

*фон Неймана.

Сортировка вставками Алгоритм. Последовательность чисел разбивают на отсортированную и не

отсортированную. Пусть первые k элементов массива уже упорядочены, для определенности, по не убыванию. Берется k+1-й элемент и размещается среди первых k элементов так, чтобы упорядоченными оказались уже k+1 первых элементов. Этот метод применяется при изменяющемся k от 1 до n-1, где n - количество элементов в заданной последовательности.

69 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

Пример. Пусть дан массив {4, 5, 2, 3, 9, 1}, который необходимо упорядочить по возрастанию, используя метод вставок.

ш1

4 | 5

2

3

9

1

5

остается на месте.

ш2

4

5 | 2

3

9

1

2

встает в начало массива.

ш3

2

4

5 | 3

9

1

3

встает за 2.

ш4

2

3

4

5 | 9

1

9

остается на месте.

ш5

2

3

4

5

9

| 1

1

встает на первое место.

 

1

2

3

4 5

9

результат.

Из примера видно, что при поиске подходящего места очередного элемента х из не отсортированного множества, необходимо этот элемент сравнивать с очередным элементом aj в отсортированном множестве и либо вставлять х, либо продвигаться влево. Таким образом, этот процесс может закончиться при двух различных условиях:

1.найден элемент aj, меньший, чем х;

2.достигнут левый конец готовой последовательности.

Реализация таких циклов была рассмотрена ранее. Здесь рассмотрим хорошо известный прием фиктивного элемента или барьера. Суть которого состоит в том, что вводится еще один элемент массива с индексом 0, величина которого равна значению элемента из не отсортированной части х, который пытаемся разместить в отсортированном множестве, т.е. а0 = х, для чего необходимо расширить диапазон индексов в описании массива от 0 до n. И пока х < aj, продолжаем двигаться по отсортированной части массива.

program sort_insert;

 

 

const

n = 30;

 

 

var

a: array [0..n] of integer;

begin

x, i, j: integer;

 

 

 

 

for i := 1 to n do

 

 

read(a[i]);

{формирование массива}

for i := 2 to n do

 

 

begin

 

 

 

x := a[i]; a[0] := x; j := i-1;

 

while x < a[j] do

{поиск места элемента в упорядоченной части}

begin

 

 

 

a[j + 1] := a[j];

{продвижение по массиву}

end;

j := j - 1

 

 

 

 

 

a[j + 1] := x

{вставка элемента в нужное место}

end;

 

 

 

for i := 1 to n do

 

 

writeln (a[i]); end.

Сортировка пузырьком (обменом)

Алгоритм. Последовательно сравниваются пары соседних элементов xk и xk+1 (k= 1, 2, ... , n-1). Если xk > xk+1, то они меняются местами. Тем самым наименьший элемент окажется на своем месте в начале массива (“ всплывет пузырек”). Затем этот метод применяется ко всем элементам, кроме первого. В результате будет найден второй элемент в отсортированном массиве и т.д.

70 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

Пример. Пусть дан массив {4, 5, 2, 3, 9, 1}, который необходимо упорядочить по

возрастанию, используя метод пузырька.

 

 

 

ш1

4

5

2

3

9

1

всплывает 1.

ш2

1

4

5

2

3

9

всплывает 2.

ш3

1

2

4

5

3

9

всплывает 3.

ш4

1

2

3

4

5

9

всплывает 4.

ш5

1

2

3

4

5

9

всплывает 5.

ш6

1

2

3

4

5

9

всплывает 9.

ш7

1

2

3

4

5

9

результат.

program bublesort;

 

 

 

 

 

const

n = 30;

 

 

 

 

 

var

a: array [1..n] of integer;

 

 

 

begin

x, i, j: integer;

 

 

 

 

 

 

 

 

 

 

 

for i := 1 to n do

 

 

 

 

 

read(a[i]);

 

{формирование массива}

for i := 2 to n do

 

 

 

 

 

for j := n downto i do

{поиск места элемента в упорядоченной части}

if a[j - 1] > a[j] then

 

 

 

 

 

begin

 

 

 

 

 

 

x := a[j - 1];

 

{меняются местами a[j-1] и a[j]}

a[j-1] := a[j];

 

 

 

 

 

 

a[j] := x

 

 

 

 

 

 

end;

 

 

 

 

 

 

 

for i := 1 to n do

 

 

 

 

 

writeln (a[i]); end.

Сортировка выбором Алгоритм. Сначала находим в массиве элемент с минимальным значением среди

элементов с индексами от 1-го до n-го и меняем местами найденный элемент с первым. После этого первый элемент из обработки можно исключить. На втором шаге находим минимальный элемент среди элементов с индексами от 2-го до n-го и меняем его местами со вторым элементом. Продолжаем повторять поиск минимального элемента и его обмен со всем элементами с 3-го до n-1-го.

Пример. Пусть дан массив {4, 5, 2, 3, 9, 1}, который необходимо упорядочить по

возрастанию, используя метод выбора.

 

 

ш1

4

5

2

3

9

1

ш2

1

5

2

3

9

4

ш3

1

2

5

3

9

4

ш4

1

2

3

5

9

4

ш5

1

2

3

4

9

5

ш6

1

2

3

4

5

9

program sort_select;

 

 

 

 

const

n = 30;

 

 

 

 

var

a: array [1..n] of integer;

 

 

 

k, i, j, x: integer;

 

 

 

begin

 

 

 

 

 

 

for i := 1 to n do

 

 

 

 

71 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

read(a[i]);

{формирование массива}

for i := 1 to n - 1 do

begin

 

k := i;

{кандидат на минимальный - первый элемент из

 

неотсортированной части}

for j := i + 1 to n do {поиск минимального в неупорядоченной части} if a[j] < a[k] then k := j;

x := a[i]; {меняются местами a[i] и минимальный} a[i] := a[k]; a[k] := x

end;

for i := 1 to n do writeln (a[i]);

end.

Сортировка фон Неймана (слиянием)

Заданы два упорядоченных по возрастанию элементов одномерных массива: a - размерности n и b - размерности m. Требуется получить третий массив с - размерности n+m, который содержал бы все элементы исходных массивов, упорядоченные по возрастанию.

Алгоритм решения этой задачи известен как "сортировка фон Неймана" или сортировка слиянием. Идея алгоритма состоит в следующем. Сначала анализируются первые элементы обоих массивов. Меньший элемент переписывается в новый массив. Оставшийся элемент последовательно сравнивается с элементами из другого массива. В новый массив после каждого сравнения попадает меньший элемент. Процесс продолжается до исчерпания элементов одного из массивов. Затем остаток другого массива дописывается в новый массив. Полученный новый массив упорядочен таким же образом, как исходные массивы.

program confluence;

const

n = 10;

 

m= 20;

 

l = n + m;

var

x: array [1..n] of integer;

 

y: array [1..m] of integer;

 

z: array [1..l] of integer;

 

k, i, j: integer;

begin

 

for i := 1 to n do

 

read(x[i]);

{формирование первого упорядоченного массива}

for i := 1 to m do

 

read(y[i]);

{формирование второго упорядоченного массива}

i := 1; j := 1; l := 1; {i -индекс первого массива, j - индекс второго массива

 

l -индекс результирующего массива}

while (i <= n) and (j <= m) do

{пока не закончились элементы в одном из

 

 

массивов}

if x[i] < y[i] then

{переписываем элемент из первого массива}

begin

 

 

z[k] := x[i];

 

 

i := i + 1; k := k + 1

end

72 Гладков В.П., Кулютникова Е.А. Пособие по информатике для самообразования.

else

 

{ переписываем элемент из второго массива}

begin

 

 

z[k] := y[j];

 

end;

j := j + 1; k := k + 1

 

 

while i <= n do

{если не закончились элементы в первом массиве,}

begin

{переписываем их в результирующий массив}

z[k] := x[i]; i := i + 1; k := k +1

end;

 

 

while j <= m do

{если не закончились элементы во втором массиве,}

begin

{переписываем их в результирующий массив}

z[k] := y[j]; j := j + 1; k := k +1

end;

 

 

for i := 1 to l do

{вывод на экран упорядоченного массива, полученного}

writeln (z[i]); {слиянием}

end.

Задача. Задан одномерный массив. Нужно упорядочить только отрицательные его элементы, оставив положительные на старых местах.

Решение. Особенностью этой задачи является то, что сортировать надо не все элементы массива, а только отрицательные. При этом можно использовать любой метод сортировки.

Вариант 1. Перепишем отрицательные элементы во вспомогательный массив, отсортируем его, а затем перепишем элементы из отсортированного вспомогательного массива в позиции отрицательных элементов в исходном массиве.

program task;

 

 

const n = 20;

 

 

var mas, mas1: array [1..n] of real;

{исходный, вспомогательный массивы}

i, j, t, k: integer;

 

 

x: real;

 

 

begin

 

 

for i := 1 to n do

 

 

read (mas[i]);

{ввод массива}

 

t := 0;

{формирование массива отрицательных элементов}

for i := 1 to n do

 

 

if mas[i] < 0 then begin t := t + 1; mas1[t] := mas[i] end;

for i := 1 to t - 1 do

{сортировка вспомогательного массива}

begin k := i;

for j := i + 1 to t do

if mas1[j] < mas1[k] then k := j; x := mas1[i];

mas1[i] := mas1[k]; mas1[k] := x end;

t := 1;

for i := 1 to n do

if mas[i] < 0 then begin mas[i] := mas1[t]; t := t +1 end; for i := 1 to n do

write (mas[i], ‘ ‘);

end.

Вопрос. Какой алгоритм сортировки использован в этой программе?

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]