Решение g6 1001: Первая мысль, приходящая в голову, это написать программу, похожую на эту: a := B; b := A




Скачать 1.77 Mb.
страница 2/11
Дата 29.08.2016
Размер 1.77 Mb.
1   2   3   4   5   6   7   8   9   10   11

Как оказалось это еще не все, теперь идет еще интереснее: наш читатель Axel нашел тест, на котором выше приведенное решение не работает.
Мы нашли количество перестановок с помощью эвристического алгоритма, однако это не всегда наименьшее количество. Теперь надо написать рекрсивную процедуру, реализующую полный перебор. Это делается точно также, (т.е. находим группу и идем от нее вправо-влево) но только мы рассматриваем два варианта - удалить диски между группами или перенести группу. При этом не забываем считать количество действие и, в случае если оно превысило значение эвристически найденного или текущего наименьшего в данный момент, то больше рекурсию не запускаем. Это позволит отсечь большую часть ненужных веток и ускорит полный перебор во много раз.

Задача g6_1017: Демократия в опасности

Л.Волков
В одном из островных государств Карибского бассейна все решения традиционно принимались простым большинством голосов на общем собрании граждан, которых, к счастью, было не очень много. Одна из местных партий, стремясь прийти к власти как можно более законным путем, смогла добиться некоторой реформы избирательной системы. Главным аргументом было то, что население острова в последнее время значительно возросло, и проведение общих собраний перестало быть легкой задачей.
Суть реформы состояла в следующем: с момента введения ее в действие все избиратели острова делились на K групп (необязательно равных по численности). Голосование по любому вопросу теперь следовало проводить отдельно в каждой группе, причем считалось, что группа высказывается "за", если "за" голосует более половины людей в этой группе, а в противном случае считалось, что группа высказывается "против". После проведения голосования в группах подсчитывалось количество групп, высказавшихся "за" и "против", и решение вопрос решался положительно в том и только том случае, когда групп, высказавшихся "за", оказывалось более половины общего количества групп.
Эта система вначале была с радостью принята жителями острова. Когда первые восторги рассеялись, очевидны стали, однако, некоторые недостатки новой системы. Оказалось, что сторонники партии, предложившей систему, смогли оказать некоторое влияние на формирование групп избирателей. Благодаря этому, они получили возможность проводить некоторые решения, не обладая при этом реальным большинством голосов!
Пусть, например, на острове были сформированы три группы избирателей, численностью в 5, 5 и 7 человек соответственно. Тогда партии достаточно иметь трех сторонников в каждой из первых двух групп, и она сможет провести решение всего 6-ю голосами "за", вместо 9-и, необходимых при общем голосовании.
Вам надо написать программу, которая определяет по заданному разбиению избирателей на группы минимальное количество сторонников партии, достаточное, при некотором распределении их по группам, для принятия любого решения.
Ввод.
Входной файл для этой задачи состоит из двух строк. В первой строке файла записано натуральное число K Вывод.
В выходной файл следует записать единственное натуральное число - минимальное количество сторонников партии, способное решить исход голосования.

Пример файла input.txt.


3
5 7 5

Пример файла output.txt.


6

Решение g6_1017:

Для контроля над группой, нам достаточно простое большинство голосов в ней. В более маленькой группе нам нужно меньше людей, чтобы иметь простое большинство голосов в ней.
Отсортируем массив с количеством людей в группе по неубыванию. Возьмем (K div 2 + 1) первых групп (минимальных) и найдем сумму всех L = G[N] div 2 + 1, где G - отсортированный массив, с количеством людей в группе, N принимает значение от 1 до K div + 1.
Группы равноправны, а мы контролируем только наименьшие.
Разделяй и властвуй.

Задача g6_1018: Пуговицы
Л.Волков
Как уже несомненно стало известно всем, Екатеринбург добился права на проведение Летних Олимпийских игр 2032 года. Планируется, что России, как стране-организатору Олимпийских игр, будет разрешено внести минимальные изменения в программу Олимпиады. Так, с целью улучшения общего командного результата, было решено заменить соревнования по плаванию первенством в абсолютно новой игре "Пуговицы".
Правила игры очень просты. Перед двумя играющими находится кучка из K пуговиц. Играющие по очереди берут пуговицы из кучки, причем за один ход каждый из них может взять от 1 до L пуговиц. Выигрывает тот из спортсменов, которому удастся взять последнюю пуговицу.
Правила олимпийских соревнований будут лишь немного сложнее обычных. Тот из игроков, которому по жребию выпадает делать первый ход, получает возможность собственноручно назначить число K, руководствуясь в своем выборе только ограничениями 3 Задача
На вашу команду возлагается очень ответственная задание: необходимо написать программу, которая помогала бы второму игроку делать свой выбор. Другими словами, по заданному числу пуговиц в кучке K, необходимо определить такое число L, которое гарантирует победу второму игроку при наилучшей игре обеих сторон.
Так, например, если в кучке всего три пуговицы, то победу второму игроку обеспечивает выбор L=2. В самом деле, если первый игрок своим ходом заберет одну пуговицу, то второй сможет выиграть, взяв обе оставшихся пуговицы и, напротив, если первый возьмет две пуговицы, то второй победит, взяв последнюю. Исходные данные
Вход для этой задачи состоит из одной строки, в которой записано единственное число K - количество пуговиц в кучке, выбранное первым игроком.
Результат
На выход следует записать единственное целое число L - максимальное количество пуговиц, которое можно взять за один ход - обеспечивающее победу второму игроку. Если таких чисел несколько, то следует вывести наименьшее из них. Если таких чисел нет, то следует вывести число 0.

Пример исходных данных


3

Пример результата


2

Решение g6_1018:


Это вроде бы простая задача. Нам достаточно разбить число пуговиц на некоторое число одинаковых групп так, что в каждой группе находится целое количество пуговиц(l), большее единицы.
Ответом будет количество пуговиц в группе - 1. Это значит, что независимо от хода первого игрока, второй игрок может дополнить имеющуюся группу пуговиц до необходимого количества(l).
Реализуется это перебором от 2 до квадратного корня из числа пуговиц, и проверкой, является ли число делителем количества пуговиц. В случае если количество пуговиц - простое число, то ответом будет K-1(легко доказывается).
Задача g6_1019: Банки
Имеется N банок с целочисленными объемами V1, ..., Vn литров, пустой сосуд и кран с водой. Можно ли с помощью этих банок налить в сосуд ровно V литров воды?
Исходная информация содержится в файле input.txt в первой строчке - количество банок N Программа должна вывести в файл output.txt одно из двух слов YES! или NO.

Решение g6_1019:


5.03.02 - автором было найдено слабое место в задаче - решение исправлено ;)
С помощью двух банок мы можем без особых ухищрений саккумулировать в сосуде количество литров, равное их наибольшему общему делителю. Например, с помощью сосудов в 5 и 3 литра, мы можем набрать любое количество воды(проверено на опыте), а их НОД равен 1.
A*x - B*y = НОД(A, B), где A и B - объемы сосудов, а x и y - некоторые величины.
Теперь задача свелась к поиску НОД двух чисел. Постараемся сделать это побыстрее. Для этого воспользуемся алгоритмом Евклида. Из двух чисел выберем большее и заменим его на остаток от деления этого числа на меньшее. Будем повторять этот шаг до тех пор, пока одно из чисел не станет равно 0, при этом оставшееся число будет равно НОД этих чисел.
Найдя НОД объемов двух первых банок (НОД(V1, V2)) будем последовательно находить НОД(НОД(V1, V2), V3) и т.д. до Vn. Теперь, если объем делится нацело на НОД, то выводим "YES!", иначе "NO".
Если вам хотелось бы ускорить процесс поиска НОД (хотя он и так работает достаточно быстро) можете почитать первую главу книги А. Шеня Программирование: теоремы и задачи
Все.

Задача g6_1020: A to B (NetOI-2000)

Я загадаю целое число из интервала [A,B]. Напишите программу, которая за минимальное число вопросов отгадает это число. Играть будем так. Я сообщаю программе числа A и B, программа выводит свою версию ответа. Если это меньше задуманного мною, я сообщу программе об этом числом -1, если больше - числом 1, а если угадано - числом 0. Так будет продолжаться, пока программа не угадает число (естественно, я буду играть честно!). Постарайтесь, чтобы ваша программа угадала число за минимальное число ходов.

Ввод-вывод: В первой строке вводите с клавиатуры два целых числа через пробел - границы диапазона. Программа на экран выводит свою версию в новой строке. С новой строки вы вводите "-1", "1" или "0" ( без кавычек). Так продолжается до того момента, пока число не будет угадано (т.е. ваш ответ "0" должен завершить работу программы).

Пример:


( я задумал число 2)
Ввод: 1 6
Вывод: 3
Ввод: 1
Вывод: 2
Ввод: 0

Ограничения : -100000

Решение g6_1020:
У нас есть два начальных числа, причем X > A и X 1) Число совпало, вываливаемся, ура!
2) Число меньше, чем X1. Тогда присваиваем B значение X.
3) Число больше, чем X1. Тогда присваиваем A значение X.
Повторяем вышеприведенные строки, до тех пор, пока не получим загаданное число.
В этом решении количество действий порядка log2(B-A), т.е. каждый раз мы уменьшаем область поиска вдвое.

Задача g6_1021: 2n

Вывести в файл output.txt число 2n, n

Решение g6_1021:
Наконец-то мы дошли до длинной арифметики! 210000 имеет порядка 3000 десятичных знаков, так что ни о каких extended'ах, а тем более longint'ах речи быть не может.
Существует такое понятие - длинная арифметика - выполнение арифметических операций в массиве (естественно, с потерями в скорости, но что же делать). В нашем случае нам нужно реализовать одно из простейших действий над длинными числами - умножение на 2.
Для надежности заведем массив длиной 4000, состоящий из элементов типа byte. Их будет достаточно для хранения одной десятичной цифры(можно хранить 2 и даже чуть больше десятичных цифр, но это сопряжено с извращениями и усложнениями, так что не будем экономить память, а будем экономить время и нервы). Обнулим массив и присвоим 4000 элементу значение 1 = 20. Затем в цикле от 1 до n будем запускать процедуру умножения на 2.
Вы наверняка хорошо представляете процедуру умножения на 2 в столбик. Здесь все точно также! Двигаясь от последнего элемента к первому(он будет определяться динамически и в начальный момент времени равен 4000), мы будем умножать его на 2 и, в случае если он превысил 9, будем брать остаток от деления на 10, а результат деления заносить в специальную переменную - так называемый флаг переноса. Это можно ассоциировать с умножением в столбик, например 8*2 - 6 пишем, 1 в уме. Главное, не забыть прибавить значение счетчика к следующему разряду.
Если цикл закончился, а флаг переноса не равен 0, то следует уменьшить счетчик, указывающий на первую цифру числа(сначала он был равен 4000), и присвоить элементу с номером счетчика значение флага переноса. В принципе, можно было проходить весь массив от конца к началу, но многократное бесполезное умножение 2 на 0 заметно снижает скорость, что немаловажно.
Стоит заметить, что некоторые предпочитают записывать младшие разряды числа в начале массива, но это непринципиально ни по размеру памяти, ни по времени работы. Кому как удобнее.
Задача g6_1022: Ниточка

А.Петров, Н.Шамгунов


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

Ваша задача - определить длину этой ниточки.


Ввод. В первой строке входного файла к этой задаче находятся два числа - количество гвоздей N, 1 Вывод. Выходной файл должен в своей единственной строке содержать вещественное число, округленное до двух знаков после запятой - длину ниточки, натянутой вокруг всех гвоздей.
Пример файла input.txt.

4 1
0.0 0.0


2.0 0.0
2.0 2.0
0.0 2.0
Пример файла output.txt.

14.28


Решение g6_1022:
Заметим, что ниточка замкнута, т.е. радиус-вектор совершил полный оборот - угол в 2pi радиан. Несложно найти длину ниточки, обходящую вокруг шляпок гвоздей - 2pi*r, где r - радиус гвоздя. Если бы все гвозди были разные, то задача была бы посложнее, а так нам осталось только найти длину ниточки, соединяющей разные шляпки. В нашм случае для этого достаточно сложить расстояния между центрами гвоздей(не забыв соединить последний гвоздь с первым). Это делается очень просто S12 = sqrt(sqr(x1-x2) + sqr(y1-y2)).
Все.
Задача g6_1023: Массивище

М. Густокашин


Во входном файле, через пробел даны числа A1, A2 ... An. Отсортировать эти числа по неубыванию и вывести отсортированный массив в выходной файл.

Входные данные


В первой строке входного файла дано число n (1 Выходные данные
В единственной строке выходного файла должен быть отсортированный массив.

Пример входного фалйа


4
4 3 1 2

Пример выходного файла


1 2 3 4

Решение g6_1023:


Это первая разобранная на сайте задача, условие которой я придумал сам! Итак, никакими стандартными средствами нам этот массив отсортировать не удастся. Сортировка слиянием, использование динамической памяти тоже не помогут (хотя кто их знает - сам не пробовал).
Идея состоит в том, что необходимо создать массив из элементов word размерностью от -15000 до 15000, изначально инициализированный нулями. При появлении очередного числа увеличиваем элемент массива с номером, равным этому числу на 1. При выводе просто проходим массив от -15000 до 15000 и выводим число, равное номеру массива столько раз, какое значение храниться в элементе с этим номером.

В этом решении есть ошибка. То есть не то что ошибка, а недоделка. А что если какое то число встречается больше 65537 раз. Тогда произойдет переполнение переменной word и восстановить массив станет невозможно! Чтобы избавиться от этой проблемы надо завести массив из 3 элементов integer, в которых будут храниться указатели на переполнившейся элемент массива. Переделать вывод результатов с использованием этого массива - задача несложная, поэтому здесь рассматриваться не будет ;)


Скачать тесты к задаче

Задача g6_1024: Знакомые

Имеется N человек и прямоугольная таблица знакомств А[1:N,1:N], в которой элемент A[i,j] равен 1, если человек i знаком с человеком j, и, соответственно, наоборот, А[i,j]=А[j,i]. Выяснить, можно ли разбить людей на 2 группы так, чтобы в каждой группе были только незнакомые люди.
Информация о знакомствах содержится в файле input.txt, в первой строке которого находится число N

6
000101


000000
000000
100000
000000
100000

Программа должна вывести в файл output.txt одно слово: YES!, если группы создать можно, и NO -- если нельзя.

Решение g6_1024:
Очередная задача со школьной OL11 (составитель М.Ю. Надточий).
Идея состоит в том, чтобы разделить людей на три части:
1)толпа - в ней стоят еще никуда не поставленные люди.
2)группа №1.
3)группа №2.
Возьмем первого человека из толпы и поставим его в одну из групп, при этом вычеркнув из толпы. Выберем всех знакомых ему людей и поставим их в другую группу. Затем для каждого из этих людей найдем его знакомых и поставим их в другую группу. На каждом шаге будем проверять, не оказался ли один и тот же человек сразу в двух группах, если оказался, то ответ NO. Такой способ дает нам гарантию, что два знакомых человека не будут в одной группе, например если два знакомых между собой человека знакомы третьему, то они оба окажутся сначала в одной группе, а затем, когда их знакомые будут переставляться в другую группу они окажутся и в другой группе.
А что делать, если в двух группах находятся незнакомые люди, а толпа еще не опустела? Тогда нужно выбрать любого человека и поставить его в любую группу (если он до сих пор в толпе, значит он не знаком ни с кем из поставленных в группы.
Главное правильно организовать проверки на то, не находится ли один человек в двух группах, и на изменение состава толпы при выборе случайного человека.
Чуть не забыл! Ответ YES надо выводить, когда толпа опустела, и каждый человек находится только в одной группе. Упс :)
Задача g6_1025: Домино

Задание. Написать программу DOMINO.*, подсчитывающую количество вариантов покрытия прямоугольника 2хN прямоугольниками 2х1. Покрытия, которые преобразуются одно в другое симметриями, считать различными.


Входные данные. Входной файл DOMINO.DAT содержит число N (0 Выходные данные. Выходной файл DOMINO.SOL должен содержать одно число: количество вариантов.

Примеры ввода и вывода

DOMINO.DAT : 1


DOMINO.SOL : 1

Решение g6_1025:


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

0 :: 1
1 :: 1
2 :: 2
3 :: 3
4 :: 5
5 :: 8
6 :: 13

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

Теперь перед нами стоит задача посчитать числа Фибоначчи до 65536 члена. Сразу замечу, что я написал программу, которая считает 65536 член Фибоначчи примерно за 30 секунд на 400-ом Селероне. Если кто-нибудь напишет быстрее, присылайте - буду очень благодарен!


Для подсчета больших чисел Фибоначчи нам понадобится длинная арифметика, причем очень длинная - около 15000 десятичных знаков. Заведем три массива длиной 20000(на всякий случай), состоящих из элементов byte. Один из массивов будет равен F(n-2), другой F(n-1), третий F(n). Первоначально инициализируем последние элементы массивов F(n-2) и F(n-1) соответственно 1 и 2. Для ускорения сложения заведем переменную, указывающую на первую цифру наибольшего числа. Первоначально эта переменная содержит 20000 (цифра одна).
Теперь перейдем к написанию процедуры сложения двух длинных чисел. Для этого нам надо идти с конца массива до указателя на первую цифру(в дальнейшем k), изменяя значение переменной c от 20000 до k.

F(n)[c] := F(n-2)[c] + F(n-1)[c] + flag;


flag := F(n)[c] div 10;
F(n)[c] := F(n)[c] mod 10;

Сложение напоминает сложение столбиком, где переменная flag - это число "в уме"(первоначально равно нулю). После сложения стоит производить такие действия:

for c := k to 20000 do begin
F(n-2)[c] := F(n-1)[c];
F(n-1)[c] := F(n)[c];
end;

Мы записываем в F(n-2) число F(n-1), а в число F(n-1) - число F(n), т.е. увеличиваем n на 1.


В конце нам следует вывести все элементы массива F(n) от k да 20000 - это и будет искомым числом!

Задача g6_1026: Монеты

Имеются монеты c различными фиксированными номиналами, выраженными в копейках (например, 3 и 5 копеек) в достаточном количестве. Написать программу COINS.*, которая:

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

Входные данные: Входной файл COINS.DAT содержит в первой строке сумму S (0

Выходные данные: Выходной файл COINS.SOL должен содержать в первой строке знак "+", если заданную сумму S можно представить, и знак "-", если нельзя. Если представленная сумма существует, то следующие N строк должны содержать количества монет каждого номинала, которые необходимы для представления суммы S с помощью минимального количества монет.

Примеры ввода и вывода

Представить 514 копеек с помощью монет номиналом в 3 и 5 копеек

COINS.DAT:


514
2
3
5

COINS.SOL:


+
3
101

Представить 27 копеек с помощью монет номиналом в 5 и 13 копеек

COINS.DAT:
27
2
5
13

COINS.SOL:


-

Решение g6_1026:


Для решения этой задачи нам понадобится знать, как находить НОД. Для этого надо прочитать Задачу #1019: Банки.
Итак, найдем НОД номиналов всех монет. Если необходимая сумма не делится на НОД нацело, то сразу выводим "-" (мы никак не можем набрать 5 рублей монетками в 2 и 4 рубля! Монеты в 4 рубля - моя идея.). Если же необходимая сумма делится на НОД без остатка, то придется действовать хитро:
Возьмем монету с наибольшим номиналом, возьмем наибольшее количество монет, так чтобы их сумма не превышала искомую сумму. Теперь посчитаем НОД оставшихся монет. Если остаток искомой суммы от тех денег, которые мы собрали, не делится на НОД, то уменьшим количество монет с наибольшим номиналом на 1 и снова проверим, делится ли остаток на НОД. Если делится - то переходим к следующей монете, если нет - то опять уменьшаем на 1 количество монет. Если в какой то момент количество монет стало отрицательным, то выводим "-" и выходим. Если вся сумма выразилась в определенном количестве монет разных номиналов, то выводим "+" и количество монет разного номинала (для хранения количества монет удобно организовать массив).
Очередная задача решена!

Задача g6_1027: Четные и нечетные члены последовательности

Даны натуральное число n, 1
Требуется получить последовательность x1, y1, x2, y2, ..., xk, yk, где x1, x2, ..., xm -- взятые в порядке следования четные (делящиеся нацело на 2) члены последовательности a1, a2, ..., an, а y1, y2, ..., yl -- взятые в порядке следования нечетные члены последовательности a1, a2, ..., an, k = min(m, l), m + l = n.

Формат входных данных


Входной файл INPUT.TXT содержит в первой строке целое число n. Во второй идут целые числа a1, a2, ..., an, разделенные пробелами.

Пример:
10


98 56 33 73 41 8 48 93 52 80

Формат выходных данных


Выходной файл OUTPUT.TXT должен содержать последовательность x1, y1, x2, y2, ..., xk, yk, расположенную в одной строке файла, числа должны быть разделены пробелами. Если исходная последовательность не содержит ни одного четного или ни одного нечетного члена, т.е. k = 0, то в файл необходимо вывести цифру 0 (нуль).

Пример:
98 33 56 73 8 41 48 93

Решение g6_1027:
Простая задача. Заведем два дополнительных массива размерностью 50, один из которых будет хранить четные, а другой - нечетные члены последовательности. Для каждого из массивов заведем собственный счетчик, указывающий на количество членов в данном массиве.
Первоначально инициализируем счетчики нулем. Затем, при чтении очередного числа, проверяем, четное ли оно и, в зависимости от четности, помещаем в один из массивов(до этого увеличив соответственный счетчик на 1).
После того, как разбиение последовательности на две закончено, найдем, какой из счетчиков меньше. В случае если минимальный счетчик раве 0 - выводим 0 и выходим, иначе последовательно выводим сначала четное число с номером n, а затем нечетное с номером n (n изменяется от 1 до min).
Задача g6_1028: Считаем кораблики

На клетчатом листе бумаги размера M*N нарисованы корабли. Каждый корабль представляет собой вертикальный или горизонтальный набор подряд идущих закрашенных клеток, разные корабли не соприкасаются по сторонам или углам и не накладываются друг на друга. В отличие от обычного "Морского боя" могут быть корабли более, чем из четырех клеток. Необходимо найти число кораблей.


Пример: лист - 12*12, кораблей - 7.

Формат входных данных


Входной файл INPUT.TXT содержит в первой строке два целых числа, разделенные пробелом, - размеры листа бумаги M и N, 2 Пример:
12 12
0 0 0 0 0 0 0 0 0 0 0 1
0 1 1 1 1 1 0 0 0 0 0 1
0 0 0 0 0 0 0 1 0 0 0 1
0 1 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0
0 1 0 1 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0

Формат выходных данных


Выходной файл OUTPUT.TXT должен содержать число (целое) кораблей на листе.

Пример:
7

Решение g6_1028:
В этой задаче нам понадобиться все кораблики "утопить". На самом деле решение простое:
Идем от левого верхнего угла по строкам (сначала просматриваем первую строку, затем вторую и т.д.). В случае если нашли "1" (кусок корабля), то увеличиваем счетчик на 1, а кораблик топим. Я топил кораблики рекурсивно, хотя здесь можно было сделать это без рекурсии, потому как кораблики не гнутые. Но с рекурсией короче и универсальнее.
У нас есть координата одного сегмента корабля и знание о том, что выше и левее от него никого нет, т.е. от этого сегмента кораблик может идти только вправо или вниз. "Утопим" этот сегмент корабля(т.е. присвоим этой клетки значение, отличное от 1). Проверим, если клетка правее содержит в себе сегмент кораблика, то нашлем на нее нашу рекурсивную процедуру-убийцу(не увеличивая счетчик - кораблик то один и тот же). Точно также поступим, если клетка снизу от нашего сегмента занята корабликом. В итоге весь кораблик будет иметь статус утопленного, и мы можем смело смотреть наше поле дальше, в поиске следующих жертв маньячной процедуры (всех кого найдет - утопит, только если этот кораблик не авианосец в форме перевернутой буквы "П", но их в этой игре вроде бы нет, да и исправить процедуры несложно :).

1   2   3   4   5   6   7   8   9   10   11


База данных защищена авторским правом ©infoeto.ru 2022
обратиться к администрации
Как написать курсовую работу | Как написать хороший реферат
    Главная страница