Задания
1. Составить программу вывода на экран изображения циферблата механических часов с секундной, минутной и часовой стрелками. Запуск часов осуществляется клавишей "Ввод", при этом перемещение секундной стрелки сопровождается "характерным" для часов звуком.
2. То же, что в задании 1, но предусмотреть режим "будильника".
3. То же, что в задании 1, но в 3, 6, 9 и 12 часов на экране появляется кукушка и подает соответствующее число сигналов и исчезает.
4. То же, что в задании 1, но предусмотреть коррекцию времени путем перемещения стрелок часов при нажатии клавиши "курсор влево" и вправо".
5. Составить программу вывода на экран настольных, электронных часов и изображение метронома. При нажатии клавиши "Ввод" стрелка метронома совершает колебательные движения, синхронно с которыми начинают изменяться показания электронных часов.
6. Составить программу вывода на экран песочных часов. При нажатии "Ввод" моделируется процесс падения песчинок, уменьшение уровня верхней части колбы и увеличение в нижней части колбы.
7. Составить программу вывода на экран спирали. При нажатии клавиши «курсор вправо» начинается вращение спирали относительно центра по часовой При нажатии клавиши "курсор влево" - против часовой стрелки.
8. Составить программу вывода на экран треугольника. При нажатии клавиши "курсор вправо" треугольник вращается по часовой стрелке вокруг одной из вершин, при нажатии клавиши "курсор влево" - против часовой.
9. Составить программу вывода на экран стилизованной "бабочки". При клавиши "Ввод" она начинает полет, взмахивая крыльями.
10. Составить программу вывода на экран стилизованного "человека" в положении готовности начать бег. При нажатии клавиши "Ввод" спортсмен начинает бежать, периодически перепрыгивая через барьеры (имитация бега с барьерами).
11. Составить программу вывода на экран стилизованного "человека" в положении готовности метнуть копье. При нажатии клавиши "Ввод" спортсмен осуществляет разбег и метает копье.
12. Составить программу вывода на экран окружности. При нажатии клавиши "курсор вправо" она вращается вокруг своего диаметра слева направо, При нажатии клавиши "курсор влево" - справа налево.
13. Составить программу вывода на экран трех горизонтальных беговых дорожек с линиями старта и финиша. На линии старта находятся три участника забега (в виде произвольных фигур). При нажатии клавиши "Ввод" участники стартуют с одинаковой начальной скоростью. Затем скорость каждого участника в процессе гонки начинает изменяться по случайному закону (т.е. изменяется пройденный путь за дискрет времени). При достижении финиша указать место, занятое каждым участником гонки.
14. Составить программу вывода на экран стилизованного "человека" в положении готовности осуществить прыжок в высоту. При нажатии клавиши "Ввод" спортсмен осуществляет разбег и перепрыгивает планку.
15. Составить программу вывода на экран стилизованного изображения "велосипедиста". При нажатии клавиши "Ввод" он начинает движение, вращая ногами педали.
16. То же, что в задания 15, но беговые дорожки представляют собой три одинаковых, расположенных рядом окружности.
17. Составить программу вывода на экран трех вложенных друг в друга прямоугольника с параллельными сторонами, которые являются беговыми дорожками. На линии старта находятся три участника забега. При нажатии клавиши "Ввод" каждый участник стартует со скоростью, пропорциональной длине беговой дорожки. После старта скорость каждого участника начинает меняться, пропорционально длине пути, по случайному закону. На финише указать место, занятое каждым участником.
18. Составить программу вывода на экран стилизованного "лыжника". При нажатии клавиши "Ввод" он начинает бег на лыжах классическим стилем.
19. Составить программу вывода на экран стилизованного "человека" в положении готовности осуществить прыжок в длину. При нажатии клавиши “Ввод” спортсмен осуществляет разбег и прыгает.
20. Составить программу вывода в верхней части экрана движущегося "корабля" с постоянной скоростью. Ее значение каждый раз задается генератором случайных чисел. В нижней части экрана расположена пушка. При нажатии клавиши "Ввод" происходит выстрел "торпедой" с постоянной, заранее заданной скоростью клавишами от 0 до 9. При попадании имитировать "взрыв"и исчезновение "корабля". При промахе "корабль" достигает правой границы и начинает движение сначала с новой постоянной скоростью.
21. То же, что в задании 20, но летящий "самолет" осуществляет бомбометание по неподвижной мишени.
22. То же, что в задании 20, но предусмотреть поворот ствола "пушки" вправо и влево с помощью клавиш управления курсором.
23. Составить программу вывода в левой части экрана изображения пушки. В правой части экрана случайным образом появляется и исчезает мишень. Нажатием клавиши "Ввод" производится выстрел из "пушки". Момент попадания фиксируется в виде "взрыва". Предусмотреть возможность перед выстрелом изменять скорость полета "снаряда" с индикацией на экране ее значения.
24. То же, что в задании 23, но между "пушкой" и "мишенью" препятствие в виде "стены" высотой от 0,25 до 0,5 экрана. Высота "стены" каждый раз после попадания в "мишень" изменяется.
25. Составить программу вывода на экран летящего "самолета" с постоянной скоростью. Ее значение может задаваться цифровыми клавишами от 0 до 9. В нижней части экрана среди "гор" расположена посадочная площадка Используя клавиши "курсор вверх" и "курсор вниз", осуществить успешную посадку "самолета" (вертолета). При аварии моделируется "взрыв".
26. Составить программу вывода в верхнюю часть экрана изображения "тучи", в нижнюю - "емкость" для воды. При нажатии клавиши "Ввод" начинает идти дождь. Размер тучи уменьшается, а "емкость" заполняется водой.
27. То же, что в задании 26, но из "тучи" идет снег и внизу растут сугробы.
28. Составить программу вывода в верхнюю часть экрана изображения двух "туч". При нажатии клавиши "Ввод" "тучи" начинают двигаться навстречу друг другу. В момент их касания начинает идти "дождь" только из перекрывающейся области, которая сначала увеличивается, а затем уменьшается по мере движения "туч".
29. Составить программу вывода на экран стилизованного "человека". При нажатии клавиши "Ввод" человек начинает идти, размахивая в такт движения руками.
30. Составить программу вывода на экран восьми вложенных друг в друга окружностей, представляющих собой беговые дорожки. На линии старта находятся восемь участника забега (произвольной фигуры). При нажатии клавиши "Ввод" участники стартуют с одинаковой угловой скоростью. После старта угловая скорость каждого участника в процессе гонки изменяется по случайному закону. На финише указать место, занятое каждым участником.
Лабораторная работа 14
Динамические структуры данных. Процедуры и функции для работы с динамическими структурами
Цель работы: Формирование умений и навыков в разработке программ создания и обработки динамических структур данных.
Что нужно знать для выполнения работы
1. Тип указатель. Процедуры и функции для работы с указателем.
2. Типы динамических структур.
Пример 1
Написать программу ввода из текстовых файлов одномерного и двухмерного массивов и вывода их на экран. Память для массивов распределить динамически во время выполнения программы.
Текст программы
program lr14_1;
{Динамические массивы
Написать программу ввода-вывода одномерного и двухмерного
массивов, память для которых распределяется динамически}
uses
crt;
Type
mas1=array[1..5] of real;
mas2=array[1..5] of ^mas1;
Var
a1:^mas1;
a2:^mas2;
fin:text;
i,j,n,m:integer;
begin
clrscr;
assign(fin,'mas1.txt');
reset(fin);
n:=0;
new(a1); {Резервируем место для одномерного массива}
while not eof(fin) do
begin
inc(n);
read(fin,a1^[n]);
end;
writeln('Исходный массив 1 ');
for i:=1 to n do
write(a1^[i]:8:0);
writeln;
dispose(a1);{Освобождаем память}
close(fin);
assign(fin,'mas2.txt'); {Матрица по строкам}
reset(fin);
n:=0;
{Резервируем место для одномерного массива указателей
на одномерные массивы-строки матрицы}
new(a2);
while not eof(fin) do
begin
inc(n);
{Резервируем место для одномерного массива указателей
на элементы n-й строки матрицы}
new(a2^[n]);
m:=0;
{Ввод очередной строки матрицы}
while not eoln(fin) do
begin
inc(m);
read(fin,a2^[n]^[m]);
end;
readln(fin);
end;
writeln;
writeln('Исходный массив 2 ');
for i:=1 to n do
begin
for j:=1 to m do
write(a2^[i]^[j]:8:0);
dispose(a2^[i]); {Освобождаем память от указателя на i-ю строку}
writeln;
end;
dispose(a2); {Освобождаем память от указателя на массив указателей}
close(fin);
readkey;
end.
Пример 2
В матрице А nxm , элементы которой могут принимать нулевые и единичные значения, подсчитайте число изолированных 0-областей, т.е. областей, состоящих из одних нулей.
Примечание. Данная задача рассматривалась в лабораторной работе № 11, но там был приведен рекурсивный вариант.
Текст программы
program L14_2;
{ В матрице А nxm , элементы которой могут принимать нулевые и
единичные значения, подсчитайте число изолированных 0-областей,
т.е. областей, состоящих из одних нулей (нерекурсивный вариант)}
uses
crt;
type
Uk=^Stek;
Stek=record
x,y:integer;
next:Uk;
end;
m2=array[0..8,0..8] of integer;
var
top:uk;
a:m2;
i,j,m,n,kol :integer;
ft:text;
procedure CreateStek(Var Top:uk);
begin
Top:=Nil;
end;
procedure PushStek(Var Top:uk;x,y:integer);
Var
Temp:uk;
begin
New(Temp);
Temp^.x:=x;
Temp^.y:=y;
Temp^.Next:=Top;
Top:=Temp;
end;
procedure PopStek(Var Top:uk;Var x,y:integer);
Var
Temp:uk;
begin
if Top<>Nil then
begin
Temp:=Top^.Next;
x:=Top^.x;
y:=Top^.y;
Dispose(Top);
Top:=Temp;
end;
end;
procedure okaiml;
begin
for i:=0 to m+1 do
begin
a[0,i]:=1;
a[n+1,i]:=1;
end;
for i:=1 to n do
begin
a[i,0]:=1;
a[i,m+1]:=1;
end;
end;
procedure Fill(i,j:integer);
var
fl:boolean;
begin
repeat
fl:=true;
if a[i-1,j]=0 then
PushStek(Top,i-1,j);
if a[i,j-1]=0 then
PushStek(Top,i,j-1);
if a[i+1,j]=0 then
PushStek(Top,i+1,j);
if a[i,j+1]=0 then
PushStek(Top,i,j+1);
if Top<>Nil then
begin
PopStek(Top,i,j);
a[i,j]:=kol+1;
fl:=false;
end;
until fl;
end;
begin
clrscr;
assign(ft,'L14_2.txt');
reset(ft);
readln(ft,n,m);
for i:=1 to n do
begin
for j:=1 to m do
read(ft,a[i,j]);
readln(ft);
end;
close(ft);
okaiml;
kol:=0;
for i:=1 to n do
for j:=1 to m do
if a[i,j]=0 then
begin
inc(kol);
a[i,j]:=kol+1;
Fill(i,j);
end;
writeln('kol= ',kol);
readkey;
end.
Пример 3
N человек встали в круг. Начиная с первого выбывает из круга каждый M-й. Составить программу, которая выводит последовательно номера выбывающих и номер оставшегося. Задача Иосифа Джозефуса.
Для реализации воспользуемся структурой «односвязное кольцо».
Текст программы
Program Lr14_3;
{Реализация задачи Иосифа Джозефуса
Структура односвязное кольцо}
Uses
Dos,Crt;
Type
Ukaz=^St;
St =record
Nomer:integer;
Next :Ukaz;
end;
Var
Nn,Left,Right,Ud : Ukaz;
N,M,ost : integer;
i,k,k1,y,x : integer;
r : registers;
Begin
clrscr;
{Организация кольца}
Write(' Количество элементов ');
Readln(N);
if N=0 then
exit;
Write(' (Выходит каждый М-й) М= ');
Readln(M);
writeln('Свободная память в начале = ',memavail);
New(Nn);
Nn^.Next:=Nil;
Nn^.Nomer:=N;
Left:=Nn;
Right:=Nn;
for i:=N-1 downto 1 do
begin
New(Nn);
Nn^.Next:=Left;{Очередной ссылается на следующий}
Nn^.Nomer:=i;
Left:=Nn;
end;
Right^.Next:=Left; {Последний ссылается на первый}
Nn:=Left;{Указатель на первый элемент кольца}
{Вывод содержимого кольца}
writeln(' Содержимое кольца ');
for i:=0 to N-1 do
begin
Write(Nn^.Nomer:4);
Nn:=Nn^.Next;
end;
{Удаление элемента из кольца}
writeln;
Writeln(' Порядок удаления элементов из круга ');
Nn:=Left;{Указатель на первый элемент кольца}
ost:=N; {Осталось элементов в кольце}
i:=1;
y:=3;
While ost>1 do {Цикл, пока осталось более одного элемента}
begin
if M=1 then
Ud:=Nn
else
begin
for i:=1 to M-2 do
Nn:=Nn^.Next;
Ud:=Nn^.Next;
Nn^.Next:=Nn^.Next^.Next;
end;
writeln(ud^.nomer:4);{Вывод номера удаляемого элемента}
Nn:=Ud^.Next;
dispose(Ud); {Удаление элемента из памяти}
ost:=ost-1;
end;
ost:=Nn^.Nomer;
write('Остался номер ');
Writeln(ost:4);
dispose(Nn);
writeln('Свободная память в конце = ',memavail);
ReadKey;
ClrScr;
End.
Пример 4
Из текстового файла TREE.TXT вводится ряд чисел, представляющих собой коды работников фирмы. Первым в этом списке код руководителя фирмы, далее коды его подчиненных, подчиненных этих подчиненных и т.д. У каждого сотрудника в непосредственном подчинении может быть не больше двух подчиненных. Если код очередного сотрудника меньше кода его непосредственного начальника, то он располагается слева от своего начальника, иначе справа. Например, если в текстовом файле содержатся числа
5
8
3
2
4
6
1
7
9
, то иерархическая лестница выглядит следующим образом (см. рисунок14.1) (в скобках указано общее количество подчиненных каждого сотрудника).
5(8)
3(3) 8(3)
2(1) 4(0) 6(1) 9(0)
1(0)
7(0)
Рисунок 14.4
Ввести коды сотрудников из файла TREE.TXT, определить обшее количество подчиненных у каждого сотрудника.
Текст программы
program Lr14_4;
{Строится бинарное дерево и подсчитывается количество
узлов и листьев, принадлежащих каждому узлу и корню
Подсчет выполняется дважды:
- во время построения дерева;
- во время обхода дерева}
uses
crt;
type
uktr=^uz;
uz=record
data :integer;
kol1,kol2 :integer; {kol1-во время построения;}
row,col,col1:integer; {kol2-во время обхода}
ur :integer;
a :char;
left,right :uktr;
end;
var
kor:uktr;
ver:uz;
ft :text;
n,i,k,k1,l,r:integer;
ch:char;
function st2(n:integer):integer;
{Степень 2. Необходима для вывода изображения дерева}
var
m,j:integer;
begin
m:=1;
for j:=1 to n do
m:=m*2;
st2:=m;
end;
function addtree(base:uktr;inf:integer):uktr;
{Добавление узла}
begin
if base=nil then
begin
new(base);
base^.data :=inf;
base^.kol1 :=0;
base^.kol2 :=0;
base^.left :=nil;
base^.right :=nil;
base^.row:=l;
base^.col:=k;
base^.col1:=k1;
base^.a :=ch;
base^.ur:=r;
end
else
begin
inc(base^.kol1);
inc(r);
l:=base^.row+4;
if base^.data>inf then
begin
k:=base^.col -st2(4-base^.ur);
k1:=base^.col-st2(3-base^.ur);
ch:='/';
base^.left :=addtree(base^.left,inf);
end
else
begin
k:=base^.col+st2(4-base^.ur);
k1:=base^.col+st2(3-base^.ur)+2;
ch:='\';
base^.right :=addtree(base^.right,inf);
end
end;
addtree:=base
end;
procedure obchod1(base:uktr);
{Обход для подсчета количества узлов}
begin
if base<>nil then
begin
obchod1(base^.left);
if base^.left<>nil then
base^.kol2:=base^.left^.kol2+1
else
base^.kol2:=0;
obchod1(base^.right);
if base^.right<>nil then
base^.kol2:=base^.kol2+base^.right^.kol2+1;
end;
end;
procedure obchod2(base:uktr);
{Обход для вывода изображения дерева}
begin
if base<>nil then
begin
obchod2(base^.left);
gotoxy(base^.col,base^.row);
write(base^.data:2,'(',base^.kol2:2,')',base^.kol1:2);
if base^.ur>0 then
begin
gotoxy(base^.col1,base^.row-2);
write(base^.a);
end;
obchod2(base^.right);
end;
end;
begin
clrscr;
assign(ft,'tree.txt');
reset(ft);
k:=32;
l:=1;
{Чтение элементов из файла и добавление их в дерево}
while not eof(ft) do
begin
r:=0;
readln(ft,ver.data);
kor:=addtree(kor,ver.data);
end;
obchod1(kor);{Обход для подсчета количества узлов}
obchod2(kor); {Обход для вывода изображения дерева}
close(ft);
gotoxy(20,24);
writeln('Дерево с количеством узлов ');
readkey;
end.