00. Осадки Анализируя статистику выпадения осадков за последние несколько лет,

advertisement
00. Осадки
Анализируя статистику выпадения осадков за последние несколько лет,
метеоролог Гадалкин сделал вывод, что весь следующий год осадки будут
выпадать, подчиняясь следующему правилу. В первый день года выпадет A
мм осадков, а в каждый следующий день будет выпадать на 1 мм больше, за
исключением тех дней, номера которых делятся на 5. В эти дни количество
осадков будет меньше на 2 мм, чем в предыдущий день. Например, если A =
4, то осадки будут выпадать следующим образом: 4, 5, 6, 7, 5, 6, 7, 8, 9, 7…
Ваша задача найти суммарное количество осадков за первые B дней года по
прогнозу метеоролога.
Входные данные. Входной файл содержит два натуральных числа A, B,
записанных через пробел. Числа не превосходят 100.
Выходные данные. Выходной файл должен содержать единственное
целое число – искомое суммарное количество осадков.
Пример:
Input.txt
4 10
Output.txt
64
Описание алгоритма. Можно просто выполнить просчет в цикле и
получить ответ. Например:
ans := 0;
for i := 1 to b do begin
if i mod 5 = 0 then dec(a,
inc(ans, a);
end;
writeln(s);
2) else inc(a);
А можно вывести не менее работоспособную формулу. Ради удобства
представим, что в последовательности чисел, являющихся количествами
осадков в определенный день, имеется первый член, равный (a – 1),
количество осадков, выпавших в мнимый первый день. Тогда данную
последовательность можно разбить на группы по пять членов (последние
члены последовательности, не составившие пятерку, пока не учитываем).
Число таких групп будет равно (b + 1) div 5 (обозначим это число буквой n).
Очевидно, что последовательность таких групп образует арифметическую
прогрессию с первым членом, численно равным (5 * a + 5), и знаменателем
10. По формуле суммы первых n членов арифметической прогрессии
получаем часть ответа: (5 * n + 5 * n) * n (после некоторых упрощений).
Понятно, что количество последних членов последовательности, не
попавших в пятерку, есть не что иное, как (b + 1) mod 5 (обозначим k). Снова
получаем маленькую прогрессию с первым членом (a – 1) + 2 * n и
знаменателем 1. Та же формула дает вторую часть ответа (a – 1) * k + 2 * n *
k + (k – 1) * k div 2. Просуммируем два результата и вычтем лишнее число (a
– 1).
01. Своя игра
В берляндском варианте известной телепередачи "Своя игра"
участвуют N человек. В течение нескольких раундов игроки, отвечая на
вопросы, зарабатывают себе очки на счет. Перед финальным раундом игроки
с неположительной суммой на счету покидают игру, то есть в финал выходят
от 0 до N человек. Случаи, когда в финал выходят менее 2 человек, нас не
интересуют.
Перед вопросом финального раунда игрокам дается список из M возможных
тем финального раунда. Игроки упорядочиваются по возрастанию набранной
ими суммы (будем считать, что все игроки всегда набирают различное число
очков) и в этом порядке начинают удалять из этого списка не нравящиеся им
темы по одной. После того, как последний из них (игрок с наибольшей
суммой) убирает тему, то очередь по циклу переходит к игроку с
наименьшей суммой. Процесс останавливается, когда в списке остается лишь
одна тема, вопрос из которой и задается в финальном раунде.
Чтобы дать игроку с наибольшей суммой некоторое преимущество, число
тем должно быть подобрано таким образом, чтобы он всегда последним
убирал тему, независимо от того, какое число игроков вышло в финал. При
этом, чтобы не затягивать процесс, число тем должно быть минимальным. К
примеру, в классическом варианте игры при N=3 участниках имеется M=7
тем финального раунда. Таким образом, если в финал вышли 3 участника, то
они удаляют темы в порядке 1-2-3-1-2-3, а если вышло 2 участника, то в
порядке
1-2-1-2-1-2.
Напишите программу, которая по заданному числу игроков N определяет
такое наименьшее число тем M, что независимо от числа финалистов (от 2 до
N) игрок с наибольшим счетом заканчивал бы выбор тем.
Входные данные
В первой строке записано целое число N (2 ≤ N ≤ 16) — число
участников
игры.
Выходные данные
Выведите минимальное число тем. Гарантируется, что при данных
ограничениях оно не превосходит 10^6.
Пример(ы)
input.txt
output.txt
2
3
input.txt
output.txt
3
7
Страница 2 из 6
Описание алгоритма. Рассмотрим число K=N-1. Из условия задачи
следует, что какое бы число игроков (P <= N) не осталось, K будет делиться
на P. Поэтому K = НОК(1,2, … N) (наименьшее общее кратное). Отметим,
что это число можно найти, всего лишь перебирая все варианты:
readln(n);
for ans:=n to 1000000 do begin
t:=0;
for i:=2 to n do if ans mod i<>1 then t:=1;
if t=0 then begin writeln(ans); exit; end;
end;
02. Театр
В театре N мест, пронумерованных целыми числами от 1 до N.
Некоторые из зрителей опоздали на спектакль. Поэтому после третьего
звонка те зрители, которые имели билеты на неудобные места, пересели на
более удобные места. Опоздавшие зрители, которые пришли уже после
третьего звонка, садились на первое попавшееся свободное место. Некоторые
места, вероятно, остались свободными.
В антракте один из опоздавших зрителей решил сесть на свое место.
Если его место до этого было занято, то тот, кто там сидел, пересаживался на
свое место. Если и там кто-то уже сидел, то и этот зритель также вынужден
был вернуться на свое место. И так далее. Поскольку в театр попали только
зрители, имевшие на руках билеты, то начавшийся в антракте процесс
пересаживания зрителей обязательно заканчивался.
Требуется написать программу, которая посчитает, сколько человек в
результате описанного процесса были вынуждены пересесть на свои места.
Входные данные. В первой строке входного файла содержится целое
число N (1  N  7500), количество мест в зале. Вторая строка содержит
последовательность из N целых чисел, разделенных пробелами, где первое
число определяет номер места в билете у зрителя, который занял место с
номером 1, второе – номер места в билете у зрителя, который занял место с
номером 2, и так далее. Если место было свободно, то соответствующее
число равно 0. Все положительные числа в последовательности различны. В
третьей строке содержится одно число – номер места в билете у опоздавшего
зрителя, который в антракте решил пересесть на свое место. Гарантируется,
что этот зритель сидел не на своем месте в зале до антракта.
Выходные данные. Выходной файл должен содержать одно число –
количество зрителей, поменявших свои места в антракте, включая
опоздавшего зрителя.
Пример:
Input.txt
10
0 2 5 3 4 0 0 0 0 0
Output.txt
3
Страница 3 из 6
4
2
2 1
1
2
Описание алгоритма. Здесь требуется найти длину цикла в
перестановке, начинающегося с заданного числа m, но цепочка перемещений
может оборваться и раньше, если в процессе нахождения цикла мы доходим
до свободного места.
readln(n);
for i:=1 to n do read(A[i]);
read(k); i:=1;
while a[i]<>k do inc(i);
A[i]:=0;
i:=0;
while true do
begin
j:=A[k];
if j=0 then begin write(i+1); exit; end;
A[k]:=k;
k:=j;
inc(i);
end;
03. Слияние строк
Даны две непустые строки S1 и S2. Ваша задача слить эти две строки в
новую строку, вставив символы одной строки между (возможно также перед
и после) символами другой строки, сохранив при этом порядок следования
символов в исходных строках. Результирующая строка должна быть
палиндромом. Палиндромом называется строка, одинаково читающаяся как
справа налево, так и слева направо.
Входные данные. Во входном файле в первой строке содержится S1, во
второй – S2. Строки состоят исключительно из заглавных букв латинского
алфавита. Длины каждой из строк не превосходят 20 символов.
Выходные данные. Выведите –1 если невозможно слить строки, чтобы
результат получился палиндромом. В противном случае выведите искомый
палиндром. Если решений несколько, выведите любое.
Примеры:
Input.txt
AACBA
BA
AC
AC
Output.txt
ABACABA
-1
Описание алгоритма. Заметим, что строка является палиндромом тогда
и только тогда, когда совпадают последний и первый символ, предпоследний
Страница 4 из 6
и второй символ и так далее до среднего символа. Таким образом, будем
сразу ставить символ и в начало и в конец. Если создавать строку, добавляя к
началу и к концу одинаковые символы, то получим палиндром. Например,
создадим палиндром длины 7.
Добавим в начало и в конец одинаковые символы. (например А)
А
А
Еще раз добавим в начало и в конец одинаковые символы. (например
П)
А
П
П
А
Добавим букву С.
А
П
С
С
П
А
Теперь осталось только добавить любой символ на центральное место.
А
П
С
К
С
П
А
Чтобы порядок символов в одной строке не менялся в начало
палиндрома можно добавлять только первый (еще не добавленный) символ
из какой-то строки. В конец можно добавлять последний. Если в начало и
конец мы будем добавлять одинаковый символы, то в конце обязательно
получим палиндром. Чтобы задать, в каком положении мы находимся,
достаточно знать номера символов, которые являются началом каждой из
строк и номера символов, которые являются концами каждой из строк.
Изначально это первые и последние символы каждой строки соответственно.
Но когда мы добавим первый символ первой строки в наш палиндром, то
началом первой строки будет второй символ.
Итак, задача решается динамикой, состоянием которой будет 4 числа:
начало первой строки, конец первой строки, начало второй строки, конец
второй строки. Переходы будут осуществляться добавлением к палиндрому
двух одинаковых символов (один в начало, другой в конец). Про каждое из
состояний мы будем знать, можно ли из этих строк получить палиндром и
если да, то какие символы нужно поставить. Если обрабатывать состояние по
увеличению суммарной длины двух строк, то значение для строк, в которые
мы захотим перейти, уже будет подсчитано. Асимптотическая сложность
такого алгоритма будет равна произведению квадратов длин строк. В нашем
случае этого вполне достаточно.
04. Игра «Перевертыши»
Поле для игры «Перевертыши» представляет собой прямоугольную
доску, расчерченную на NM квадратов. На каждом квадрате есть кнопка и
лампочка. Лампочка может гореть одним из трех цветов: красным, зеленым
или синим. При нажатии на кнопку какой-либо клетки меняется цвет
лампочки на ней и на всех клетках, имеющих с данной общую сторону.
Смена цвета всегда осуществляется по правилу: красный меняется на
зеленый, зеленый на синий, а синий на красный. Цель игры: за наименьшее
количество нажатий кнопок добиться того, чтобы лампочки на всем поле
Страница 5 из 6
светились одним цветом. Ваша задача написать программу, которая находит
это количество.
Входные данные. В первой строке входного файла содержатся два
натуральных числа N и M (1 ≤ N, M ≤ 10), где N – количество строк на доске,
а M – количество столбцов. Далее в N строках содержится описание
начального состояния поля. Поле задается цветами лампочек на каждой
клетке. Символ «R» обозначает красный цвет, «G» – зеленый, а «B» – синий.
Выходные данные. В выходной файл выведите единственное целое
число – наименьшее количество нажатий кнопок, необходимое для того,
чтобы лампочки на всем поле светились одним цветом. Если решения не
существует, выведите –1.
Примеры:
Input.txt
5 5
BBBGG
BBBBG
BBBBB
GBBBB
GGBBB
1 3
RRG
Output.txt
2
1
Описание алгоритма. Допустим, что мы знаем, как правильно
нажимать на кнопки, чтобы получить оптимальное решение. Тогда мы знаем
цвет, к которому нужно привести всю таблицу и сколько раз нужно нажать
на кнопки, находящиеся в первом ряду. Стоит заметить, что, зная это, можно
однозначно восстановить все последующие нажатия. Во втором ряду мы
должны нажать на кнопку ровно столько раз, чтобы в первом ряду в этой же
позиции загорелся правильный цвет, так как эта кнопка единственная,
которая может повлиять на лампочку сверху. Таким образом, если последний
ряд оказался правильного цвета, то это один из вариантов решения. Среди
всех вариантов нужно выбрать лучший, что и будет ответом.
Итак, мы перебираем, сколько раз нажать на каждую кнопку в первом
ряду и цвет, в который мы хотим перекрасить всю таблицу. Далее
однозначно восстанавливаем остальные нажатия. В случае правильного цвета
всей последней строки, пересчитываем ответ. Примерное количество
действий: 3n * 3 * n * n, что при данных ограничениях не превосходит 2*107.
Страница 6 из 6
Download