Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SB_13.doc
Скачиваний:
8
Добавлен:
11.05.2015
Размер:
962.05 Кб
Скачать
  1. Разработка алгоритмов

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

0. Математическая модель. Определение соотношений между величинами, существенных для поставленной задачи, и математическая запись этих соотношений.

1. Входные данные: отдельные переменные и массивы, типы данных, наличие особенностей в значениях. Описание и комментирование, ввод.

2. Результаты: переменные и массивы, типы, связь между количеством входных значений и количеством результатов. Описание и комментирование, вывод.

3. Тесты: наборы входных значений, для которых известны результаты. Учет возможных особенностей во входных значениях.

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

5. Запись программы: на основе разработанного алгоритма программа собирается из отдельных готовых фрагментов.

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

Эффективность программы оценивается по уровню использования ею ресурсов компьютера: процессорного времени и оперативной памяти. Например, из двух программ, написанных для решения одной и той же задачи, более эффективной будет та, которая формирует результат путем выполнения меньшего количества элементарных действий. Говорят, что эта программа имеет большее быстродействие. Для оценки эффективности программы определяется функция зависимости количества элементар­ных действий от размера входных данных. Эту функцию называют трудоемкостью. Более эффективной является программа, обладающая меньшей трудоемкостью.

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

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

B2 (4 мин)

У исполнителя Арифметик две команды, которым присвоены номера:

1. Прибавь 2,

2. Умножь на 3.

Первая из них увеличивает число на экране на 2, вторая утраивает его.

Например, 21211 – это программа

умножь на 3

прибавь 2

умножь на 3

прибавь 2

прибавь 2,

которая преобразует число 1 в число 19.

Запишите порядок команд в программе преобразования числа 3 в число 69, содержащей не более 5 команд, указывая лишь номера команд. Если таких программ более одной, то запишите любую из них.

Ответ: ___________________________.

РЕШЕНИЕ

Задачу удобнее решать от конца к началу. Получить в конце 69 можно после выполнения любой из двух команд. Поскольку разрешенное количество команд ограничено, нужно выбрать ту, которая обеспечит большее изменение: умножь на 3. Значит, предыдущее значение будет 69 / 3 = 23. 23 может получиться только после выполнения прибавь 2. 23 – 2= 21. Число 21 может получиться после выполнения умножь на 3. 21 / 3 = 7. 7 может получиться только после выполнения прибавь 2. 7 – 2 = 5. Первой командой должна быть прибавь 2.

Итак, нужно выполнить такую последовательность действий:

+ 2 + 2 * 3 + 2 * 3 . Их всего 5.

Ответ: 11212

C2 (30мин)

Дан целочисленный массив из 30 элементов. Элементы массива могут принимать целые значения от 0 до 100. Опишите на русском языке или на одном из языков программирования алгоритм, позволяющий найти и вывести произведение элементов массива, которые имеют нечётное значение и делятся на три. Гарантируется, что в исходном массиве есть хотя бы один элемент, значение которого нечётно и кратно трем.

Исходные данные объявлены так, как показано ниже. Запрещается использовать переменные, не описанные ниже, но разрешается не использовать часть из них. Исходные данные всегда подобраны так, что результат произведения не выходит за пределы объявленных типов данных.

Паскаль

Алгоритмический язык

const

N = 30;

var

a: array [1..N] of longint;

i, j, p: longint;

begin

for i := 1 to N do

readln(a[i]);

end.

алг

нач

цел N = 30

целтаб a[1:N]

цел i, j, p

нц для i от 1 до N

ввод a[i]

кц

...

кон

Бейсик

СИ

N = 30

DIM A(N) AS LONG

DIM I, J, P AS LONG

FOR I = 1 TO N

INPUT A(I)

NEXT I

END

#include <stdio.h>

#define N 30

void main (void){

long a[N];

long i, j, p;

for (i=0; i<N; i++)

scanf("% d", &a[i]);

}

Русский (естественный) язык

Объявляем массив A из 30 элементов.

Объявляем целочисленные переменные I, J, P.

В цикле от 1 до 30 вводим элементы массива A с 1-го по 30-й.

В качестве ответа Вам необходимо привести фрагмент программы (или описание алгоритма на естественном языке), который должен находиться на месте многоточия. Вы можете записать решение также на другом языке программирования (укажите название и используемую версию языка программирования, например, Free Pascal 2.4) или в виде блок-схемы. В этом случае Вы должны использовать те же самые исходные данные и переменные, какие были предложены в условии (например, в образце, записанном на естественном языке).

РЕШЕНИЕ

Основа алгоритма – определение тех элементов массива, которые имеют нечетное значение и делятся на 3. Проверка на нечетность значения: a[i] mod 2 =1. Проверка делимости на 3: a[i] mod 3 =0. В таком случае окажется, что значение 0 делится на 3 без остатка. Однако проверка на нечетность покажет, что 0 – четное число. Следовательно, нулевые значения не будут участвовать в умножении.

Программа на Паскале:

const

N = 30;

var

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

i, j, p: integer;

begin

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

p:= 1; {начальное значение для произведения}

for i:=1 to N do

if (a[i] mod 2 = 1) and (a[i] mod 3 = 0)

then p:=p * a[i];

writeln(p);

end.

Переменная j не понадобилась.

C4 (55мин)

На вход программе подаются сведения о пассажирах, желающих сдать свой багаж в камеру хранения на заранее известное время до полуночи. В первой строке сообщается число пассажиров N, которое не меньше 3, но не превосходит 1000; во второй строке – количество ячеек в камере хранения K, которое не меньше 10, но не превосходит 1000. Каждая из следующих N строк имеет следующий формат:

<Фамилия> <время сдачи багажа> <время освобождения ячейки>,

где <Фамилия> – строка, состоящая не более чем из 20 непробельных символов;

<время сдачи багажа> – через двоеточие два целых числа, соответствующие часам (от 00 до 23 – ровно 2 символа) и минутам (от 00 до 59 – ровно 2 символа);

<время освобождения ячейки> имеет тот же формат.

<Фамилия> и <время сдачи багажа>, а также <время сдачи багажа> и <время освобождения ячейки> разделены одним пробелом. Время освобождения больше времени сдачи.

Сведения отсортированы в порядке времени сдачи багажа. Каждому из пассажиров в камере хранения выделяется свободная ячейка с минимальным номером. Если в момент сдачи багажа свободных ячеек нет, то пассажир уходит, не дожидаясь освобождения одной из них.

Требуется написать программу (укажите используемую версию языка программирования, например Borland Pascal 7.0), которая будет выводить на экран для каждого пассажира номер ему предоставленной ячейки (можно сразу после ввода данных очередного пассажира). Если ячейка пассажиру не предоставлена, то его фамилия не печатается.

Пример входных данных:

3

10

Иванов 09:45 12:00

Петров 10:00 11:00

Сидоров 12:00 13:12

Результат работы программы на этих входных данных:

Иванов 1

Петров 2

Сидоров 1

РЕШЕНИЕ

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

1. Входные данные. Значения входных данных находятся в строках символов. Значит, для ввода понадобится символьная (char) или строковая (string) переменная.

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

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

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

Описание переменных:

var sym : char;

fam : string;

N, K : integer;

cell : array[1..1000] of integer;

Можно оформить ввод:

readln(N); readln(K);

for i := 1 to N do begin

чтение очередной строки;

выделение ячейки пассажиру;

end;

2. Результаты.

Информация, на основе которой будут выводиться результаты, сохраняется в массиве cell.

3. Тест.

Исходные данные (K=3)

Результаты

Соколов

Микитов

Золотов

Серебров

Сибиряков

Югов

Востоков

Закатов

12:30

14:10

15:15

15:20

17:50

18:35

18:35

20:45

15:10

18:00

18:40

19:00

20:40

23:55

22:35

21:55

Соколов

Микитов

Золотов

Серебров

Югов

Закатов

1

2

1

3

2

1

4. Разработка алгоритма.

Общая схема алгоритма имеет следующий вид:

начальные значения;

for i := 1 to N do begin

чтение очередной строки;

выделение ячейки пассажиру;

end;

Проведем детализацию отдельных блоков алгоритма.

чтение очередной строки

В начале строки находится фамилия пассажира. Далее через пробел следуют 2 последовательности символов в формате ЧЧ:ММ. При вводе строку нужно разделить на смысловые части. Время удобнее сразу пересчитывать в минуты, чтобы облегчить последующее сравнение.

fam:=’’;

sym := !; {этот символ не может быть в начале фамилии}

while sym <> do begin {чтение фамилии}

read(sym); fam:= fam+sym;

end;

hour:=’’; minute:=’’;

read(sym); hour := hour+sym; {чтение часов}

read(sym); hour := hour+sym;

read(sym); {чтение двоеточия}

read(sym); minute :=minute +sym; {чтение минут}

read(sym); minute :=minute +sym;

val(hour, inthour, code1); {процедура преобразования строки в число}

val(minute, intminute, code2);

if (code1=0) and (code2=0)

then minute_in:= inthour*60+ intminute

else begin writeln(’Ошибка в данных’); halt; end;

hour:=’’; minute:=’’;

read(sym); {чтение пробела}

read(sym); hour := hour+sym; {чтение часов}

read(sym); hour := hour+sym;

read(sym); {чтение двоеточия}

read(sym); minute :=minute +sym; {чтение минут}

readln(sym); minute :=minute +sym;

val(hour, inthour, code1); {процедура преобразования строки в число}

val(minute, intminute, code2);

if (code1=0) and (code2=0)

then minute_out:= inthour*60+ intminute

else begin writeln(’Ошибка в данных’); halt; end;

выделение ячейки пассажиру

j := 1;

while (j <= K) and (cell [ j ] > minute_in) do j := j + 1;

if j <= K then begin

writeln(fam, ’,j); {выделение ячейки пассажиру}

cell [ j ] := minute_out;

end;

начальные значения

for i := 1 to K do cell [ i ] := 0;

На этом разработка алгоритма закончена.

5. Запись программы.

program nazv;

var fam : string;

sym : char;

N, K : integer;

cell : array[1..1000] of integer;

i, j : integer;

begin

readln(N); readln(K);

for i := 1 to K do cell [ i ] := 0;

for i := 1 to N do begin

fam:=’’;

sym := !; {этот символ не может быть в начале фамилии}

while sym <> do begin {чтение фамилии}

read(sym); fam:= fam+sym;

end;

hour:=’’; minute:=’’;

read(sym); hour := hour+sym; {чтение часов}

read(sym); hour := hour+sym;

read(sym); {чтение двоеточия}

read(sym); minute :=minute +sym; {чтение минут}

read(sym); minute :=minute +sym;

val(hour, inthour, code1); {процедура преобразования строки в число}

val(minute, intminute, code2);

if (code1=0) and (code2=0)

then minute_in:= inthour*60+ intminute

else begin writeln(’Ошибка в данных’); halt; end;

hour:=’’; minute:=’’;

read(sym); {чтение пробела}

read(sym); hour := hour+sym; {чтение часов}

read(sym); hour := hour+sym;

read(sym); {чтение двоеточия}

read(sym); minute :=minute +sym; {чтение минут}

readln(sym); minute :=minute +sym;

val(hour, inthour, code1); {процедура преобразования строки в число}

val(minute, intminute, code2);

if (code1=0) and (code2=0)

then minute_out:= inthour*60+ intminute

else begin writeln(’Ошибка в данных’); halt; end;

j := 1;

while (j <= K) and (cell [ j ] > minute_in) do j := j + 1;

if j <= K then begin

writeln(fam, ’,j); {выделение ячейки пассажиру}

cell [ j ] := minute_out;

end;

end;

end.

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