Консультация № 160955
20.02.2009, 07:57
60.00 руб.
0 1 1
Здравствуйте! Помогите, пожалуйста, написать программы (с комментариями):
1. Задача Джозефуса. Данная задача представляет собой своего рода считалку. Формальное описание алгоритма этой считалки. Для этого элементы "становятся в круг", вводится некоторое число k. Необходимо, начиная с первого, отсчитать k-й элемент списка и удалить его. Далее отсчет начинается с k+1 элемента и опять удаляется k-ый элемент. Так продолжается до тех пор, пока в списке не останется один элемент. Необходимо выдать содержимое последнего оставшегося элемента (например, строку). Для решения использовать кольцевой список.
2. Дана последовательность из не менее чем двух различных натуральных чисел. Напечатать в обратном порядке все числа между наибольшим и наименьшим числами этой последовательности. Использовать двумерный список.

Обсуждение

Неизвестный
20.02.2009, 17:42
общий
это ответ

Здравствуйте, [b]Student_[/b]!

Примеры находятся в приложении.

В первом примере нужно ввести два числа: n (размерность списка) и k.

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

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

Удачи!

Приложение:
======================== Задача №1 ========================

program Q160955_1;

type
{ Элемент кольцевого списка }
PCNode = ^TCNode;
TCNode = record
data: Integer;
next: PCNode;
end;

var
cirList, next: PCNode;
i, k: Byte;
tmp: Integer;
begin
{ Создаем список }
GetMem(cirList, sizeof(TCNode));
cirList^.next:= cirList;
{ Первый элемент }
cirList^.data:= 1;

{ Получаем n - количество элементов }
write('n = '); readln(k);

{ Заполняем список }
for i:= 2 to k do
begin
next:= cirList^.next;
GetMem(cirList^.next, sizeof(TCNode));
cirList:= cirList^.next;
cirList^.next:= next;
cirList^.data:= i;
end;

{ Вводим k }
repeat
write('k = '); readln(k);
until(k > 0);

{ Пока в списке не останется }
{ всего один элемент }
while (cirList <> cirList^.next) do
begin
{ Отсчитываем k-1 элемент }
for i:= 2 to k do
cirList:= cirList^.next;
{ Следующий элемент - k-й }
next:= cirList^.next;
cirList^.next:= next^.next;
{ Удаляем k-й элемент }
FreeMem(next, sizeof(TCNode));
end;

{ Выводим номер оставшегося элемента }
writeln('result = ', cirList^.data);
{ Удаляем последний элемент }
FreeMem(cirList, sizeof(TCNode));

{ Ждем, пока пользователь не }
{ нажмет [Enter] }
Readln;
end.


======================== Задача №2 ========================

program Q160955_2;

type
{ Элемент двунаправленного }
{ связного списка }
PDLNode = ^TDLNode;
TDLNode = record
data: Integer;
prev: PDLNode;
next: PDLNOde;
end;

var
dList, lFirst, lLast, next, prev: PDLNode;
i: Byte;
iMin, iMax, inp: Integer;
begin
{ Создаем список }
GetMem(dList, sizeof(TDLNode));
dList^.next:= nil;
dList^.prev:= nil;

{ Вводим число последовательности }
write('1: '); readln(inp);

{ Инициализация }
i:= 2;
iMin:= inp;
iMax:= inp;
dList^.data:= inp;
lFirst:= dList;
lLast:= dList;

{ Ввод последовательности }
while (True) do
begin
write(i, ': '); readln(inp);
{ Если inp не натуральное число, }
{ завершаем ввод }
if (inp < 1) then
Break;

{ Создаем новый элемент списка }
GetMem(dList^.next, sizeof(TDLNode));
dList^.next^.prev:= dList;
dList:= dList^.next;
dList^.next:= nil;
dList^.data:= inp;

{ Проверяем на максимум }
if (inp > iMax) then
begin
{ Если максимум был в начале }
if (iMax = lFirst^.data) then
{ Переносим минимум в начало }
lFirst:= lLast;
lLast:= dList;
iMax:= inp;
end
{ Проверяем на минимум }
else if (inp < iMin) then
begin
{ Если минимум был в начале }
if (iMin = lFirst^.data) then
{ Переносим максимум в начало }
lFirst:= lLast;
lLast:= dList;
iMin:= inp;
end;

Inc(i);
end;

writeln('result:');
{ Проверка на всякий случай... }
if (lFirst <> lLast) then
{ Перебираем элементы в }
{ обратном направлении }
while (lFirst <> lLast^.prev) do
begin
lLast:= lLast^.prev;
writeln(lLast^.data);
end;

{ Удаляем список из памяти }
while (dList <> nil) do
begin
lLast:= dList^.prev;
FreeMem(dList, sizeof(TDLNode));
dList:= lLast;
end;

{ Ожидаем, пока пользователь }
{ не нажмет [Enter] }
Readln;
end.
Форма ответа