Задания по выч. практике. 1 семестр 2 курс.

ТРЕБОВАНИЯ К ПРОГРАММАМ
  1. Необходимо точно выполнять условия задач, при сомнениях -- консультироваться с преподавателем. Программы представляются в исходных текстах.
  2. Текст программы должен быть откомментирован. В заголовке указать имя автора, группу, краткую формулировку задания. Переменные должны иметь осмысленные имена. Желательно объявление переменной снабжать комментарием о ее назначении.
  3. Следует структурировать программу, разбивая ее на (относительно) независимые части. Осуждается порочная практика размещения многих операторов в одной строке.
  4. Длинные программы (свыше 200 строк) следует разбивать на несколько файлов и создавать проект. Это обязательное требование, так как умение работать с проектами квалифицированному программисту необходимо.
  5. Интерфейс программы должен быть достаточно удобен для пользователя.
  6. Программа должна компилироваться без ошибок и предупреждений при всех включенных сообщениях компилятора.
  7. Исходные данные в любом из заданий, если это не оговорено особо, должны вводиться с клавиатуры или из файла, а именно: если при запуске программы в командной строке указано имя файла, то исходные данные читаются из него, в противном случае - вводятся с клавиатуры.

ЗАДАЧИ НА ОДНОМЕРНЫЕ СТРУКТУРЫ

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

2. Расстояние между двумя словами равной длины - это количество позиций, в которых различаются эти слова. В заданном предложении найти пару наиболее далеко удаленных слов заданной длины.

3. Отредактировать заданное предложение, удаляя из него те слова, которые встречаются в предложении заданное число раз

4. Найти самое длинное общее слово двух заданных предложений.

5. Отредактировать заданное предложение, удаляя из него те слова, которые уже встречались в предложении раньше.

6. Для встречающихся в заданном тексте пар рядом расположенных символов указать сколько раз встречается в тексте каждое из таких двухбуквенных сочетаний.

7. Даны два предложения. Найти самое короткое из слов первого предложения, которого нет во втором предложении.

8. Найти самое длинное симметричное слово заданного предложения.

9. Напечатать множество слов, которые встречаются в каждом из двух заданных предложений.

10. Для каждого из слов заданного предложения указать, сколько раз оно встречается в предложении.

11. Напечатать в алфавитном порядке все латинские строчные буквы, входящие хотя бы в одно слово заданного текста.

12. Отредактировать заданное предложение, удалив из него слова, которые уже встречались ранее.

13. Из заданного текста выбрать и напечатать те символы, которые встречаются в нем ровно один раз ( в том порядке, в котором они встречаются в тексте).

14. Отредактировать заданное предложение, удаляя из него все слова с нечетными номерами и переворачивая слова с четными номерами.

15. В текстовом файле заменить все символы табуляции на n пробелов. Результат записать в новый файл. Имя выходного файла по умолчанию - out.txt. Число n задается пользователем, по умолчанию n=8. Пусть исполняемый файл имеет имя change, тогда программа запускается так:
D>change in_file.txt [out_file.txt] [n]


ЗАДАЧИ НА ДВУМЕРНЫЕ СТРУКТУРЫ

16. Среди тех строк целочисленной матрицы, которые содержат только нечетные элементы, найти строку с максимальной суммой модулей элементов.

17. Подсчитать количество строк заданной целочисленной матрицы NxN, являющихся перестановкой чисел 1,2...N (т. е. содержащих каждое из чисел 1,2...N ровно один раз.

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

19. Массивом char[M][N] кодируется поле, на котором расположено несколько прямоугольников. Каждый состоит из целого числа клеток, разные прямоугольники не накладываются друг на друга и не соприкасаются. Разные прямоугольники могут состоять из разных символов. Один и тот же прямоугольник не может состоять из различных символов. Пустые квадраты поля кодируется символом '.'. Подсчитать число прямоугольников разных типов. Поле вводится с клавиатуры или читается из файла. Пример:
###...??..+.
###.=.??..+.
###.......+.
.....???....
???.......==
???...####..
Для этого поля программа должна выдать ответ:
#-прямоугольников: 2
?-прямоугольников: 3
+-прямоугольников: 1
=-прямоугольников: 2

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

21. Для заданной матрицы размером NxN найти такие k, что k-я строка матрицы совпадает с k-м столбцом.

22. Развертка кодируется массивом строк (переменной длины), например:
const char* m1[ ] =
{ ".#",
"##",
".#"}
const char* m2[] =
{ ".#.",
"##.",
".#.",
".##" }
Написать функцию check_map, проверяющую, является ли данная развертка разверткой куба (перехлесты не допускаются):
enum boolean {true, false};
boolean check_map(char** map);
Для check_map (m1) == false, check_map (m2) == true. Развертка должна вводиться с клавиатуры или читаться из файла.

23. Начиная из центра, обойти по спирали все элементы матрицы NxN, распечатывая их в порядке обхода.

24. Для заданной целочисленной квадратной матрицы найти максимум среди сумм элементов диагоналей, параллельной главной диагонали.

25. Начиная с элемента a_11 обойти по спирали квадратную матрицу NxN, распечатывая элементы в порядке обхода.

26. Найти максимальный среди всех элементов тех строк заданной матрицы, которые упорядочены (либо по возрастанию, либо по убыванию).

27. По заданной квадратной матрице NxN построить вектор длиной 2n-1,элементы которого - максимумы элементов диагоналей, параллельных главной.

28. Напечатать элементы заданной матрицы размером NxN в следующем порядке

        ._. ._.
         \.\.\.\.
          \.\.\!
!\.   ...   \.\.
.\.\.         \!
!\.\.\.
.\.\.\.\.
~   ~
начиная с правого верхнего угла.

29. Напечатать элементы заданной матрицы размером NxN в следующем порядке

._. ._. .
././././       .
!/././       ./!
././  ...  ././.
!/       ./././!
       ././././.
         ~   ~
начиная с левого верхнего угла.

30. Расстояние между k - й и l - й строками матрицы A(NxN) определяется как

	   N
	   __
           \
      r =  /    ( | a  | * | a  | )
	   ~~        kj       lj
	  j=1

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


ЗАДАЧИ НА ДИНАМИЧЕСКИЕ ТИПЫ ДАННЫХ

Если в задаче этого раздела не указан тип списка, считать его однонаправленным. На уровне программы считать, что список - это указатель на начало первого элемента списка.

31. Написать программу, работающую с 2-х мерным динамическим массивом вещественных чисел, границы которого могут быть произвольными целыми числами (не обязательно от 0 до n):

struct arr                  // двумерный массив
{ double** base;
  int d1_lower, d1_higher;
  int d2_lower, d2_higher;
};

Напишите функции:

int init(arr& t, int d1_l, int d1_h, int d2_l, int d2_h, double
initial);
// разместить в памяти 2-x-мерный массив t
// c границами от d1_l до d1_h по первой размерности и от d2_l до
// d2_h по второй размерности и заполнить его значением initial

int kill(arr& t);
// освободить память, занятую 2-мерным массивом t

double get(arr a, int i, int j);
// получить значение массива a в координатах i, j.
// При неверных границах выдавать сообщение об ошибке.

double put(arr a, int i, int j, double d);
// поместить в координаты i, j массива a элемент d.
// При неверных границах выдавать сообщение об ошибке.

double find_max(arr a);
// Найти максимум в массиве a.

Void print(arr a);
// Распечатать массив c указанием координат элементов.

Следующий код:

arr a;

init (a, 2, 5, -2, 2, -1);
put (a, 2, 0, get(a, 2, 0) + 10);
printf("%f\n", find_max(a));
print(a);
kill(a);

должен выдать на печать примерно следующее:
9

        -2      -1      0       1       2
2	-1	-1	9	-1	-1
3	-1	-1	-1	-1	-1
4	-1	-1	-1	-1	-1
5 	-1	-1	-1	-1	-1

32. Написать набор функций, позволяющих работать с бинарным деревом вещественных чисел.
а. Ввести дерево из файла. Формат ввода: в каждой строке файла - одно число с плавающей точкой, перед которым могут стоять символы табуляции. Пусть в какой-то строке стоит число n в позиции k. Тогда потомки числа n стоят в последующих строках в позиции (k+1). Пример. Следующий файл:

5
        6
                7
		8
                        -10
                        -5
        9
                11
                13

кодирует дерево
                      5
                   /     \
		 /	   \
		6	    9
             /    \        /  \
            7      8     11    13
                 /   \
              -10    -5

б. Определить число вхождений числа k в бинарное дерево
в. Напечатать наибольший элемент непустого дерева

33. Написать набор функций, позволяющих работать с бинарным деревом вещественных чисел:
а. Ввести дерево из файла. Формат ввода: в каждой строке файла - одно число, перед которым могут стоять символы табуляции. Пусть в какой-то строке стоит число n в позиции k. Тогда потомки числа n стоят в последующих строках в позиции (k+1). Пример. Следующий файл:

5
        6
                7
                8
                        -10
                        -5
        9
                11
                13

кодирует дерево
                      5
                   /     \
		 /	   \
		6	    9
             /    \        /  \
            7      8     11    13
                 /   \
              -10    -5
б. Вычислить сумму элементов непустого дерева
в. Напечатать элементы всех листьев дерева
г. Определить число ветвей в самом длинном из путей от корня дерева до листьев.

34. Программа должна находить среднее арифметическое элементов непустого однонаправленного списка вещественных чисел, заменять все вхождения числа x на число y, менять местами первый и последний элементы, проверить, упорядочены ли числа в списке по возрастанию.

35. Напечатать текст в обратном порядке, напечатать слова текста в обратном порядке. Использовать стек строк.

36. Вводятся два списка строк. Написать следующие функции:
а. сравнить списки на равенство
б. определить, входит ли первый список во второй
в. скопировать в конец списка второй список

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

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

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

40. Даны два списка l1 и l2 пар вещественных чисел. Написать функции, возвращающие новый список l, включающий
а. пары списка l1, первая координата которых встречается как вторая координата у пар списка l2
б. пары (x,y) списка l1 встречающиеся в виде (y,x) в списке l2
в. пары (x,y) x 41. Даны два списка l1 и l2 вещественных чисел. Написать функции, возвращающие новый список l, включающий по одному разу числа, которые
а. входят одновременно в оба списка
б. входят хотя бы в один из списков
в. входят в один из списков l1 и l2, но в то же время не входят в другой из них
г. входят в список l1, но не входят в список l2.

42. Объединить два упорядоченных по неубыванию списка вещественных чисел в один упорядоченный по неубыванию список. Реализовать в двух вариантах:
list* join1(list *l1, list *l2);
void join2(list **l1, list **l2),
а. функция join1() возвращает новый список, не меняя списки *l1 и *l2
б. функция join2() не создает нового списка, а меняет соответствующим образом ссылки в l1 и l2. После объединения списков *l1 и *l2 оба указывают на начало списка-результата.

43. Целое число представляется строкой цифр. Написать функцию, упорядочивающую по неубыванию числа в непустом списке целых чисел с S разрядами.

44. Дан список слов среди которых есть пустые. Написать функции:
а. переставляющие местами первое и последнее непустые слова
б. печатать текст из первых букв непустых слов
в. удалить из непустых слов первые буквы
г. определить количество слов в непустом списке, отличных от последнего

45. Иерархический список - последовательность, состоящая из строк или иерархических списков. Начало и конец списка будем обозначать символами ( и ). Разделять элементы списка будем запятой. Написать следующие функции:
а. Дана строка, обозначающая иерархический список. Строка содержит маленькие латинские буквы, скобки и запятые. Пример такой строки: "((ab,c),midst,(),last)". Преобразовать такую строку в иерархический список.
б. проверка вхождения строки в иерархический список
в. печать всех строк, входящих в иерархический список на любой глубине
г. проверка на равенство двух списков


СЛОЖНЫЕ ЗАДАЧИ
46. МАТЕМАТИЧЕСКИЕ ФУНКЦИИ
Разработать библиотеку для работы со структурами, реализующими вещественные функции от одного аргумента.
Набор операций над функцией:
- сложение, умножение, вычитание, деление;
- возведение в целочисленную степень;
- суперпозиция функций;
- вычисление значения функции при заданном аргументе (предусмотреть обработку ситуации, когда аргумент лежит вне области определения);
- инициализацию функции символьной строкой func_init( f, "exp(x) + (x^2 - 4.4x^3) / cos(x)" );
- преобразование "функции" из внутреннего представления в символьную строку;
- фиксированное число стандартных элементарных функций (sin,cos,tg,ctg,log,exp);
- вычисление производной функции (результат -- функция).
Внутреннее представление "функции" -- дерево.

47. ПОЛИНОМЫ - 1
Разработать набор функций для работы с полиномами от одной переменной с вещественными коэффициентами.
Действия над полиномами:
- сложение, умножение, вычитание;
- возведение в целую степень;
- взятие коэффициента при заданной степени;
- определение степени полинома;
- вычисление значения по заданному аргументу;
- суперпозиция полиномов;
- инициализация символьной строкой; pol_init( f, " x^12 + 2 * x^11 - 3 * x + 17 " ); в записи полинома символьной строкой переменная всегда обозначается символом "x". Лишние пробелы игнорируются.
- преобразование из внутреннего представления в символьную строку;
- вычисление производной;
- вычисление первообразной (с нулевой константой);
Внутреннее представление -- список пар (коэф,степень). При выполнении всех операций необходимо приводить подобные.

48. ПОЛИНОМЫ - 2
Разработать набор функций для работы с полиномами вещественными коэффициентами.
Действия над полиномами те же, что и в задаче 47. Внутреннее представление полинома -- массив. При выполнении всех операций необходимо приводить подобные.

49. ДЛИННЫЕ ЧИСЛА
Реализуйте набор функций для работы с целыми числами с неограниченным числом цифр. Число хранится в двоичном виде, память под массив данных должна выделяться динамически.
Действия над длинными числами:
- сложение, вычитание, умножение, деление нацело, взятие остатка, деление с остатком, возведение в целую степень;
- операции сравнения двух длинных чисел; - инициализация символьной строкой bigint_init( i, "12345678901234567890");
- преобразование из внутреннего представления в символьную строку;
- взятие абсолютной величины числа.

50. ШИФРОВКА
Реализовать программу шифровки и дешифровки по алгоритму DES Национального бюро стандартов США (описание можно найти в книге: Дейтел Г. Введение в операционные системы. Том 2. М.: Мир, 1987.). Программа должна шифровать бинарный файл произвольной длины и декодировать закодированный файл. Ключ шифровки сохраняется отдельно от шифруемого файла.

51. ШАХМАТЫ
Написать программу, решающую задачи "мат в N ходов". Входные данные - файл с записью позиции. Результат - файл с записью начальной позиции и ходами сторон.
Написать программу, наглядно демонстрирующую шахматные ходы. Программа должна иметь графический интерфейс. Входными данными программы является файл с записью начальной позиции и ходов в шахматной нотации.

52. ФОРМАТИРОВАНИЕ ТЕКСТА
Написать программу, читающую текст из файла и выводящую его в другой файл отформатированным -- в процесс форматирования пользователь не вмешивается. В исходном тексте абзацы разделены пустыми строками. Во входном файле могут встречаться строки, которые не записываются в выходной файл, а содержат только команды для программы форматирования.
Пример:
Текст на этой строке не содержит команд форматирования
.pagelength 25
.newpage
Перед этой строкой команда .newpage вставляет разделитель страниц.

Команды форматирования:
- параметры страницы (длина, количество пустых строк сверху/снизу)
- параметры абзаца (отступ первой строки, отступ всех остальных строк, длина строки);
- нумерация страниц (нумеровать или нет, номер первой страницы в файле, номер страницы вверху/внизу);
- установить колонтитул;
- временная отмена форматирования (текст переносится "как есть");
- расположение текста на строке: влево, по центру, вправо, к краям;
- перенос да/нет;
Разработать алгоритм переноса русских слов (один из вариантов в [1]).
[1] Абрамов С.А. и др. Задачи по программированию /Биб-ка программиста/. М.: Наука, 1988.

53. РЕВЕРСИ
Написать программу для игры "реверси". Программа должна работать в двух режимах:
- играют два человека
- человек играет против компьютера.
Реализовать алгоритм игры за компьютер. Предусмотреть запись позиции в файл, считывание позиции из файла, откат к предыдущей позиции на любое число ходов.

54. ЖИЗНЬ
Написать программу для игры Конвея "Жизнь", работающую в графическом режиме с игровым полем достаточно больших размеров (необходимо прокручивание экрана). Программа должна позволять менять параметры игры:
- условия возникновения жизни и вымирания в клетке;
- размеры игрового поля;
- количество поколений между показами / задержка при пошаговой демонстрации.
Пользователь должен иметь возможность редактировать игровую конфигурацию, сохранять ее в файл, считывать из файла (со всеми параметрами), запускать пошаговую демонстрацию, выделять прямоугольный фрагмент, копировать, перемещать в любое место поля, записывать фрагмент на диск и считывать с диска.

55. ОКОННАЯ СИСТЕМА
Разработать оконную библиотеку для работы в графическом режиме. Окно может содержать некоторый текст; если текст не вмещается полностью, то его можно просмотреть прокручиванием. В систему должны включаться окна как с неизменяемым, так и с изменяемым размером. Окно можно закрыть. Окно с изменяемым размером можно раскрыть на весь экран или минимизировать. Окно может иметь заголовок. Окно можно двигать по экрану.
Количество одновременно открытых окон не ограничивается. Каждое окно имеет номер, пользователь может переходить из окна в следующее или в окно с заданным номером. Написать программу демонстрирующую возможности оконной библиотеки.

56. ЭВМ
Некоторая ЭВМ имеет объем оперативной памяти 1024Кбайт, из которых 150 Кбайт занимает оперативная система (помещается в младших адресах памяти), а остальные доступны для задач,которые запускаются с единственного терминала, имеющегося на ЭВМ, причем запуск очередной задачи может быть произведен раньше, чем закончится предыдущая. Запущенная задача помещается в оперативную память и начинает выполняться, если для нее имеется достаточно оперативной памяти, свободной к моменту запуска.В противном случае задача помещается в очередь.В дальнейшем как только память освободиться, первая задача из очереди, для которой требование по памяти выполняются, начинает работать.
Оперативная память задаче выделяется непрерывным куском. Если для задачи, первой в очереди, не имеется достаточного по размеру непрерывного куска, ОС проверяет, не получится ли такой непрерывный кусок, если сдвинуть вверх все имеющиеся в ОП задачи и собрать, таким образом, все свободное пространство в один кусок. Если это возможно, ОС производит такую операцию и запускает задачу. Если это невозможно, сжатие не производится, а ОС пытается запустить подобным образом вторую задачу из очереди и т.д.
После окончания задачи занятая ею память освобождается и может быть распределена другим задачам.
По команде оператора задаче может быть выделена дополнительная память. Если в ОП сразу вслед за данной задачей имеется достаточный свободный участок, то он просто передается задаче. Если такого участка нет, то его можно создать, то производится сжатие, как сказано выше, причем нижерасположенные задачи перемещаются к началу ОП, а вышерасположенные к концу (сели достаточно одного из этих действий, то второе не производится), после чего образовавшийся свободный участок передается задаче. Если и таким образом нельзя получить свободную память, запрос отвергается с выдачей диагностики.
Время при работе системы квантуется равными порциями для всех задач, находящихся в ОП. Например, если в ОП имеется 3 задачи, то за 1 мин. каждая из них получит 0.33 мин.
Команды оператора по работе с системой:
1. INT интервал. Задает интервал (в мин.), через который система выходит на диалог с оператором. По умолчанию INT=1. При выходе на диалог машинное время останавливается.
2. RUN имя_задачи время память. Запустить задачу.
Имя -- идентификатор из <= 6 символов.
время -- целое число в интервале 1..60,
память -- целое число в интервале 1..MAXV, где MAXV -- максимально
допустимый в системе объем ОП. При задании величины >MAXV задача не принимается.
3. EXT имя_задачи память. Расширяет память на указанное целое число Кбайт. Действует только на выполняющиеся задачи, для задач в очереди команда отвергается.
4. CPU. Выдает информацию о состоянии ОП. Для каждой задачи указывается какие адреса она занимает. Указываются также свободные участки. Желательна выдача этой информации в виде псевдографической карты памяти (см., например, карту диска в SD,NU). Для задач также указывается время, прошедшее от начала и время, оставшееся до конца.
5. QUE. Выдает информацию об очереди (задачи,заказанное время и память).
6. CAN имя_задачи Если задача выполняется,аварийно прекращает или ее с выдачей сообщения и освобождает память. Вариант CAN/ALL. CAN/ALL аварийно прекращает все выполняющиеся задачи. На задачи в очереди команда не действует.
7. ERA имя_задачи Аналогична команде CAN, но действует на задачи в или очереди и не действует на задачи в ОП. ERA/ALL
8. STO имя_задачи. Если задача выполняется, приостанавливает ее. Для приостановленной задачи время "не идет", а остальные задачи, находящиеся в ОП в этот момент, делят ее время между собой. На задачи в очереди команда не действует.Приостановленная задача может быть снята командой CAN или возобновлена командой CON.
9. CON имя_задачи. Возобновляет выполнение приостанавливаемой задачи. На выполняющиеся (не остановленные) и задачи в очереди не действует. После выполнения команды CON задача вновь получает свою долю процессорного времени.
10. HOL. Задерживает всю очередь и запрещает старт новых задач (они ставятся в очередь).
11. HOL имя_задачи. Задерживает задачу в очереди. Задержанная задача не может быть запущена, даже если есть свободная память. Задержанная в очереди задача может быть снята командой DEL или отпущена командой UNH.
12. UNH. Отменяет команду HOL.
13. UNH имя_задачи. Снимает статус задержки, устанавливаемый командой HOL. Если задача не задержана, команда игнорируется.
12. GO. Конец диалога, возврат в режим выполнения.
13. EXI. Выход из системы.
Система должна вызывать ответ на любую введенную команду (сообщать о результате действий по выполнению команды), обеспечить диагностику в случае неверного синтаксиса команд или неверных по смыслу действий (например, удаление несуществующей задачи и т.п.). Кроме того, автоматически (т.е. не при выходе на диалог, а в момент, следующий за событием) должны выдаваться сообщения о старте или окончании задач.
Примечание: Не разрешается запуск задачи с некоторым именем, если в ЭВМ (в ОП или очереди) имеется задача с таким же именем.

57. ТЕКСТОВЫЙ РЕДАКТОР
Написать полноэкранный текстовый редактор. Редактор должен обладать следующими возможностями:
-- загрузка текстового файла с диска и сохранение текста в файл,
-- показ текста в окне с прокруткой по горизонтали и вертикали,
-- построчное и постраничное листание текста, перемещение курсора (клавиши: стрелки, PgUp, PgDown, Home, End),
-- вставка и удаление символов и строк (клавиши Del, BackSpace),
-- возможность набора текста в режимах вставки и замещения (переключатель режимов - клавиша Insert).
Редактор должен быть написан в текстовом режиме.

58. ПРИВЕДЕНИЕ ФОРМУЛЫ ИВ К ДНФ
Формулой логики высказываний называется последовательность символов, построенная по правилам:
1) переменная есть формула,
2) если A и B формулы, то выражения (A&B), (AvB), (A>B), ^A тоже формулы.
Скобки в формулах могут быть опущены с учетом ассоциативности связок & и v, а также согласно правилам приоритета логических связок:
^ (наибольший приоритет),
&,
все остальные связки.
Разработать динамическую древовидную структуру данных FormTree для записи информации о формуле логики высказываний. Разработать функции, реализующие следующие возможности:
-- перекодировка из строкового представления формулы в FormTree;
-- перекодировка из FormTree в строковое представление;
-- приведение заданной формулы к ДНФ (аргумент и результат типа FormTree).

59. ПРИВЕДЕНИЕ ФОРМУЛЫ ИВ К КНФ
Формулой логики высказываний называется последовательность символов, построенная по правилам:
1) переменная есть формула,
2) если A и B формулы, то выражения (A&B), (AvB), (A>B), ^A тоже формулы.
Скобки в формулах могут быть опущены с учетом ассоциативности связок & и v, а также согласно правилам приоритета логических связок:
^ (наибольший приоритет),
&,
все остальные связки.
Разработать динамическую древовидную структуру данных FormTree для записи информации о формуле логики высказываний. Разработать функции, реализующие следующие возможности:
-- генерация случайной формулы логики высказывания, длина которой не превосходит заданное число (результат имеет тип FormTree);
-- перекодировка из FormTree в строковое представление;
-- приведение заданной формулы к КНФ (аргумент и результат типа FormTree).

60. ОСТРОВА В МОРЕ
Расположение островов в море представлено картой размером N*N. Задача заключается в восстановлении карты по закодированной информации о распределении островов по горизонтали и вертикали.
На следующем примере острова обозначены символом *, море - символом -.

* - * * - -  1 2
- * * * - *  3 1
* - * - * -  1 1 1
- * * * * *  5
* * - * - *  2 1 1
- - - * - -  1
1 1 4 2 2 1
1 2   3   2
1
Числа справа и снизу являются кодами и представляют собой информациюо порядке и размерах групп островов в соответствующих строках (столбцах). Например, числа 1 2 в первой строке означают, что первая горизонталь содержит группу из одного острова, за которой следует группа из двух островов. Справа и слева от каждой группы расположено море произвольной протяженности.
ПОСТАНОВКА ЗАДАЧИ.
Код карты записан в файле в виде блока, имеющего следующий формат (то, что написано после #, является комментарием):
N                          # размер карты
1 2 0                      # код первой строки
3 1 0
1 1 1 0
5 0
2 1 1 0
1 0
1 1 1 0                    # код первого столбца
1 2 0
4 0
2 3 0
2 0
1 2 0
Коды строк и столбцов заканчиваются 0. Входной файл может содержать несколько подобных блоков.
1) Напишите программу, восстанавливающую карту по ее коду (все карты в случае не единственного решения). Восстановленные карты должны быть записаны в текстовый файл. Остров обозначается *, море - символом -. Формат выходного файла:
   Карта 1             # карта, восстановленная по первому коду
   Вариант 1           # 1-й вариант такого восстановления
       Рисунок 1-го варианта карты

   Вариант 2
       Рисунок 2-го варианта карты

   Вариант 3
       Рисунок 3-го варианта карты

   Карта 2               # В случае единственного варианта
   Вариант 1
       Рисунок карты 2

   Карта 3
       !!! Нет карты !!! # В случае отсутствия решения