- •Тема: Перебор вариантов. Задача 1. Замечательные числа
- •Задача 2. Острова
- •Задача 3 Клавиатура
- •Задача 4 . Вырубка деревьев
- •Краткие методические рекомендации по решению задачи
- •Оценка решения
- •Формат входных данных
- •Формат выходных данных
- •Работа с большими числами
- •Золото племени абба
- •Сортировка и поиск
- •2. Домашнее задание.
- •Метод перебора вариантов, отсечения перебора
- •Сумма двух чисел
- •Элементы вычислительной геометрии
- •4. Две окружности
- •Эффективные структуры данных
- •5. Поиск прямоугольников (Время: 0,5 сек. Память: 16 Мб Сложность: 34%)
- •Тема 1: «Работа с длинными числами»
- •Тема 2: Алгоритмы поиска и сортировки
- •Тема 3: Аналитическая геометрия
- •Тема 4: Перебор вариантов
- •Тема 5: Строки. Элементы лексического и синтаксического разобра
- •Задача 3. "Функция"
- •Ограничения
- •Площади покрытия антенны
- •Площадь покрытия решение
- •Элементы лексического и синтаксического разбора Шифровка
- •Шифровка Решение
- •Сортировка и поиск Независимые судьи
- •Независимые судьи Решение
- •Сувениры
- •Сувениры Решение
- •Треугольник Условие задачи
- •Треугольник Решение
- •Олимпиадные задачи по информатике
- •Задача 1. «Код да Винчи»
- •Задача 3 «Буквы»
- •Задача 4 «Соревнования»
- •Задача «Красивая последовательность»
- •Тема: Задача на динамическое программирование
- •Динамическое программирование Задача: Черепашка
- •Решение
- •Тема: Работа с большими числами
- •Тема: Сортировка и выбор
- •Задача. Подземная дорога (поиск в ширину)
- •Формат входных данных
- •Задача rebus
- •Задача “Эчпочмаки”
- •Задача “Ниточка”
- •Задача “Обезьяны”
- •Задача Интересное число
Задача 3. "Функция"
Условие задачи.
Функция F(n) для целых неотрицательных n определена так: F(0)=0, F(1)=1, F(2n) = F(n), F(2n+1)=F(n)+F(n+1).
Для данного N найти и напечатать F(n). Обязательное условие: N
столь велико, что недопустимо заводить массив из N чисел.
Алгоритм решения.
Основная идея алгоритма заключается в том, что при разложении f(2n+1) на f(n) и f(n+1) мы должны вычислить 2 значения функции. Либо n, либо n+1 окажется нечетным и для его вычисления понадобится опять вычислять 2 значения функции. А для четного аргумента еще одно. На первый взгляд, кажется, что теперь нам надо вычислить значения F для 3 аргументов, но на самом деле 2 из них (аргументов) всегда совпадут! То есть кол-во вычислений функции на каждом шаге не увеличивается.
Пример:
F(26) = F(13) = F(6)+F(7) = F(3)+F(3)+F(4) = 2F(3)+F(4) =
=2(F(1)+F(2))+F(2) = 2F(1)+3F(2) = 5F(1) = 5
Программная реализация
Program func; var
c, {Текущий четный аргумент}
nc, {Текущий нечетный аргумнт}
kc, {Коэффициент при четном аргументе}
knc, {Коэффициент при нечетном аргументе} n:LongInt;
{В переменной c всегда должен быть четный аргумент, а в nc - нечетный. Эта процедура меняет местами значения переменных c и nc, если это необходимо}
Procedure Correct; var Temp:LongInt;
Begin
if odd(c) then Begin Temp:=c; c:=nc; nc:=Temp; Temp:=kc; kc:=knc;
knc:=Temp; End;
End;
Begin
Write('Введите число '); ReadLn(N);
n:=abs(n); {Вычислим модуль n} if n=0 then Writeln('0') else
Begin
while n mod 2 = 0 do n:=n div 2; {уменьшаем n до нечетного числа}
c:=n div 2; {Разложим n на четное}
nc:=n-c; {и нечетное числа} if c=0 then kc:=0 else kc:=1;
knc:=1;
while (c>2) or (nc>2) do Begin
Correct; {поменяем c и nc, если нужно}
c:=c div 2; {получим новый аргумент}
kc:=kc+knc; {получим коэфф. при нем}
nc:=nc-c; {вычислим второй аргумент} End;
WriteLn(Kc+knc); {Выведем результат} ReadLn; {Подождем}
End; End.
Задача 4 „REBUS“.
Составить программу REBUS, которая определяет все 4-значные числа на интервале [M, N], удовлетворяющие условиям: a) abcd - 4-цифровое число; b) a, b, c, d - разные цифры; c) ad - cd = a + b + c + d; и подсчитывает общее количество этих чисел. Во входном файле REBUS.DAT в 1-м и 2-й строчках находятся два числа M и N. В файле REBUS.SOL выводятся числа, удовлетворяющие условиям а)-с), и их количество.
файл REBUS.DAT |
файл REBUS.SOL |
5128 5467 |
5139 5302 2 |
program REBUS; var a,b,c,d,m,n,k,x,i:integer; f,f1,f2:text; begin assign (f,'rebus.dat'); readln(m,n); rewrite(f); writeln(f,m); writeln(f,n); close(f); for i:=m to n do begin a:=i div 1000; b:=i mod 1000 div 100; c:=i mod 100 div 10; d:=i mod 10; if (a <> b) and (a <> c) and (a <> d) and (b <> c) and (b <> d) and (c <> d) and (a*d-c*d=a+b+c+d) then begin k:=k+1; assign(f1,'rebus.sol'); append(f1); writeln(f1,i); close(f1); end; end; assign(f1,'rebus.sol'); rewrite(f1); writeln(k); writeln(f1,k); close(f1)
end.
Задача 4 „ Кубики. “.
Кубик с ребром N см покрасили и разрезали на кубики с ребром 1 см. При этом появились такие, у которых окрашено разное количество граней. Например, если N = 3, то после разрезания будет 8 кубиков, у которых окрашено три грани, 12 с двумя гранями, 6 с одной, а один кубик будет совсем неокрашенный. Составьте программу, которая бы определяла, сколько кубиков с каждой возможным количеством окрашенных граней.
Технические условия |
|||||||
Имя программы |
CUBES. |
||||||
Ввод |
С клавиатуры вводится целое число N (от 1 до 1292) |
||||||
Вывод |
На экран или форму выводятся различные варианты окрасок и их количества в формате: количество_окрашеных_граней/количество_кубиков в порядке возрастания первого параметра
|
||||||
program cubes; uses crt; var x,x1,x2,x3,x0,y,z,k,n:integer; s:string; f,g:text; begin assign(f,'cubes.dat'); reset(f); readln(f,y); close(f) ; x3:=8; x1:=sqr(y-2)*6; x0:=(sqr(y-2))*(y-2); x2:=(y-2)*4*2+(y-2)*4; assign(g,'cubes.sol'); rewrite(g); writeln(g,'0/',x0,' 1/',x1,' 2/',x2,' 3/',x3); close(g); end.
Тема: Сортировка и поиск
Задача “Шифровка”
Мальчик Петя чрезвычайно увлекается различными шпионскими рассказами и недавно от чтения романов со стрельбой и погонями перешел к изучению серьезной литературы. Особенно его заинтересовал один из методов шифровки секретных сообщений, прочитанный им в брошюрке по криптографии из серии “Библиотечка кровавого режима”.
Метод заключается в следующем: среди большого количества чисел спрятано то, которое несет секретную информацию, причем все числа встречаются трижды (или кратное трем число раз), кроме секретного числа, которое встречается некратное трем число раз. Так как Петя был маленьким и обладал чрезвычайно живым воображением, то он представил себе сотни шифровщиков с красными глазами, сидящих под зелеными лампами и с огромной напряженностью выискивающих секретное число на распечатках, ошибающихся и рвущих на себе волосы. Однако в реальности такой шифр легко взламывается компьютерной программой, которую вам предстоит написать.
Формат входных данных
Во входном файле записано целое число N — количество чисел (1 ≤ N ≤ 300 001). Далее записано N целых чисел Mi (1 ≤ Mi ≤ 2•109).
Формат выходных данных
В выходной файл выведите секретное число.
Ограничение
Ограничение по памяти (при решении данной задачи можно было использовать не более 1 Мб оперативной памяти) и количество чисел не дает возможности ни сохранить все числа для последующей сортировки, ни даже просто запомнить их в единственном экземпляре; кроме того, исходя из ограничения по времени и количества чисел, можно сделать вывод, что задача должна решаться за линейное время.
Алгоритм решения
Разобьем каждое двузначное число на разряд десятков и разряд единиц (однозначные числа будут иметь в качестве разряда десятков 0)
Получим две цифры
Посчитаем, сколько раз встречалось каждая цифра
Выберем то, которое встречалось некратное трем число раз, его индекс и будет ответом(один проход по массиву и подсчет остатка от деления каждого элемента на 3).
Умножим цифру десятков на 10 и прибавим к ней цифру единиц.
Решение
Program shifr;
uses crt;
var
A : array[1..10, 0..9] of longint; {объявление двухмерного массива}
i, j, k, n: longint; f1, f2: text;
begin
assign(f1,’input.txt’); reset(f1);
assign (f2,’output.txt’);rewrite (f2);
for i := 1 to 10 do
for j := 0 to 9 do
{заполняем таблицу нулями }
A[i, j] := 0;
read(f1,n);
for i := 1 to n do begin
read(f1,k);
j := 1; {номер разряда}
while k <> 0 do begin
{на месте j добавилась цифра k mod 10}
inc(A[j, k mod 10]);
{выкидываем последнюю цифру }
k := k div 10;
{переходим к следующему разряду}
inc(j);
end;
end;
k := 0; {здесь будем восстанавливать число начиная со старших разрядов}
for i := 10 downto 1 do begin
{ переходим к следующей цифре}
k := k * 10;
{перебираем все цифры}
for j := 0 to 9 do
{нашли "секретную" цифру}
if A[i, j] mod 3 <> 0 then
{и прибавляем ее к ответу}
k := k + j;
end;
writeln(f2,k);
close (f1);
close (f2);
end.
Тестирование задачи
Input.txt |
Output.txt |
11 3 1 2 3 1 3 2 2 1 3 3 |
3 |
10 22 12 34 22 12 22 12 34 34 25 |
25 |
Тема: Эффективные структуры данных
Задача Роботы
Сообщество роботов живет по следующим законам: один раз в год они объединяются в полностью укомплектованные группы по 3 или 5 роботов (причем число групп из 3 роботов - максимально возможное). За год группа из 3 роботов собирает 5, а группа из 5 - 9 новых собратьев. Каждый робот живет 3 года после сборки. Известно начальное количество роботов k, все они только что собраны. Определить, сколько роботов будет через n лет.
Входные данные
В первой строке исходного файла Input.txt записано начальное число роботов, во второй строке – количество лет.
Выходные данные. В файл Output.txt выведено одно число – искомое количество роботов
Input.txt |
Output.txt |
13 7 |
10603
|
Алгоритм решения
Создадим массив r[3], где r[1], r[2], r[3] - количество роботов соответствующего возраста. Т
Обозначим x - количество троек, y - количество пятерок, которое можно сформировать из общего числа роботов.
Определим возможное количество троек и пятерок роботов.
Вычислим количество создаваемых роботов 5*х+9*у в год
Тогда общее количество роботов S= r[1] + r[2]+ r[3].
Programrobotu;
vark,i,n:integer;
fi,fo:text;
p:byte;
s,x,y:longint;
r:array [1..3] oflongint;
begin
assign (fi,’input.txt’); reset (fi); read (fi,n); close (fi);
assign (fo,’output.txt’); rewrite (fo);
r[1]:=k; r[2]:=0; r[3]:=0; s:=k;
{заполним массив, исходное количество роботов-первый элемент массива}
for i:=1 to n do begin
{открываем цикл с количеством повторений,равным количеству лет}
x:=sdiv 3; {находим возможное количество троек роботов}
p:=smod 3; {находим остаток роботов}
casepof {рассматриваем варианты создания групп по три и пять роботов}
0: y:=0; {если остаток равен нулю, будут только тройки роботов}
1: beginx:=x-3; y:=2;end; {если 1, то забираем три тройки и создаем две пятерки}
2: beginx:=x-1; y:=1;end; {если остаток 2, то забираем одну тройку и создаем одну пятерку}
end;
r[3]:=r[2]; r[2]:=r[1]; r[1]:=5*x+9*y;
{добавляем в массив число вновь созданных роботов}
{формируем массив, в котором данные обновляются каждый год}
s:=r[1]+r[2]+r[3];
{роботы, прожившие более трех лет, автоматически убираются из массива}
end;
write(fo, s);
close (fo);
end.
Тестирование задачи
Начальное число роботов |
Число лет |
Количество роботов |
8 |
1 |
22 |
8 |
2 |
60 |
10 |
5 |
1286 |
10 |
10 |
143702 |
15 |
3 |
273 |
200 |
2 |
1424 |
1000 |
10 |
13284366 |
Тема: Элементы вычислительной геометрии.
Задача «Отрезок»
Условие задачи. Отрезок на плоскости задается двумя несовпадающие конечными точками A (x1; y1) и B (x2; y2). С точки С (х3; у3) к прямой, содержащей отрезок АВ, проводится перпендикуляр. Определить, попадает перпендикуляр на отрезок АВ или на его продолжение.
Во входном файле содержится три пары чисел, являющихся координатами точек А, В, С.
В выходном файле содержится ответ «На отрезок» или «На продолжение». Пример входного и выходного файлов
S.txt |
S1.txt |
4 4 7 3 9 5 |
На продолжение |
