В выходной файл выводится одно число –минимальное

advertisement
Районные олимпиады по программированию
Задача №1 «Быстрое возведение в степень» (max 100 баллов)
При возведении числа в степень только с помощью операции умножения, ее можно
использовать минимальное количество раз. Например, чтобы вычислить число a в десятой
степени, можно найти a*a*a*a*a*a*a*a*a*a (9 умножений) или найти b=a*a*a (a3), c=b*b*b (a9),
d=c*a (a10) (5 умножений). Для заданного показателя степени найти минимальное количество
необходимых умножений.
Входные данные – показатель степени числа.
Выходные данные – минимальное количество умножений.
Требования к выполнению: задача оценивается в 100 баллов, удачное прохождение
теста – 20 баллов.
Фрагмент программы на языке Паскаль:
begin
Write(‘n=’); readln(n);
k := n; s = 0
While k > 1 do begin
If k mod 2 = 1
then k = k - 1
else k = k / 2;
s = s + 1 end;
Writeln(s)
end.
Задача №2 «Расшифровка многораундного шифра»
(max 100 баллов)
Один раунд шифратора F(S) строки S работает в два этапа по следующему правилу:
1. На первом этапе строка S заменяется строкой, в которой сначала располагаются все
буквы строки S, стоящие на позициях с номерами, являющимися числами Фибоначчи (первый
блок), а затем все остальные символы (второй блок), относительный порядок букв в каждом
блоке остается неизменным.
2. На втором этапе получившаяся строка инвертируется. Первый символ становится
последним, второй- предпоследним, и т.д. для всех символов строки.
Функция шифрования к тексту S может применяться многократно, в несколько раундов:
Зная k (1≤k≤32767) – количество раундов шифрования Fk (S) = F(F… F (S) …) k раз и
зашифрованное сообщение Fk (S) (длина S не превосходит 255), осуществите дешифровку
строки Fk (S) .
Напомним, что числа Фибоначчи – элементы числовой последовательности 1, 1, 2, 3, 5, 8,
…, в которой каждый последующий член равен сумме двух предыдущих.
При одном раунде, например, строка S=abcdefgh на первом этапе шифруется в строку
S=gfdhecba. На втором этапе S примет вид S=bchaedfg.
Пример входных и выходных данных:
Пример 1
Входные данные:
2
BCHAEDFG
Пример 2
Входные данные:
1
вещественное
Выходные данные:
ABCDEFGH
Выходные данные:
еоннвтеесщев
1
Текст программы на языке Turbo Pascal
Program Shifr;
Var
s,s1,s2:string;
i,j,l,m,n,k:integer;
Function Fib(x:integer):boolean;{Функция, выясняющая}
Var
{является ли данное число}
f1,f2,f3:integer;
{числом Фибоначчи}
Begin
f1:=1;
f2:=1;
f3:=f1+f2;
While f3<=x do
begin
f1:=f2;
f2:=f3;
f3:=f1+f2;
end;
if f2=x then Fib:=true else Fib:=false
End;
BEGIN
Writeln('Введите количество фаз');
Readln(k);
Writeln('Введите фразу для дешифровки');
Readln(s);
for i:=1 to k do
begin
s1:='';
for j:=length(s) downto 1 do {инвертируем строку}
s1:=s1+s[j];
m:=0;
{Вычислим количество
чисел}
for j:=1 to length(s) do
{Фибоначчи на отрезке от
1}
if Fib(j) then m:=m+1;
{до длины строки s}
m:=m+1; {позиция, начиная с которой находятся символы,
стоящие на местах с номерами, не являющимися числами
Фибоначчи}
l:=1; {позиция, начиная с которой находятся символы,
стоящие на местах с номерами, являющимися числами
Фибоначчи}
s:='';
for j:=1 to length(s1) do
if Fib(j) then
begin
s:=s+s1[l];
l:=l+1
end
else
begin
s:=s+s1[m]; m:=m+1
end
end;
Writeln(s);
END.
2
Задача №3 «Замена слов» (max 100 баллов)
B заданном тексте одно заданное слово везде заменить на другое заданное слово такой же
длины (100 баллов).
Требуется написать программу, которая решает названную задачу.
Исходные данные: текст, слово1 и слово2 вводятся с клавиатуры.
Выходные данные: новый текст выводится на экран.
Текст программы.
Turbo Pascal
(эта программа, использующая стандартную функцию Pos , не требует, чтобы длины
заменяемого и вставляемого слов были одинаковыми)
Program Replace;
Uses Crt;
Var Text, Slovo1, Slovo2 : String;
i, DlinaSlova, P
: Integer;
BEGIN ClrScr;
Write('Введите строку : '); ReadLn(Text);
Write('Какое слово заменить ? '); ReadLn(Slovo1);
Write('На какое слово заменить ? '); ReadLn(Slovo2);
WriteLn; WriteLn('О т в е т : ');
WriteLn('Исходный текст: ', Text); DlinaSlova:=Length(Slovo1);
DlinaSlova:=Length(Slovo1);
P:=Pos(Slovo1,Text); {номер позиции, с которой в строке Text
}
{в первый раз встречается подстрока Slovo1 }
While P>0 do
{цикл продолжается до тех пор,пока подстрока}
{Slovo1 встречается в строке Text
}
begin
Delete(Text, P, DlinaSlova); {удаление подстроки Slovo1, начинаю-}
{щейся с позиции P, из строки Text }
Insert(Slovo2, Text, P); {вставка подстроки Slovo2 }
{ в строку Text с позиции Р}
P:=Pos(Slovo1, Text); {номер позиции, с которой подстрока Slovo1}
{встречается в строке Text в очередной раз}
end;
WriteLn('Новый текст: ', Text);
ReadLn
END.
Задача №4 «Лексикографическое упорядочение слов»
Заданную последовательность слов переупорядочить в алфавитном порядке.
Требуется написать программу, которая решает названную задачу.
Исходные данные: последовательность слов вводится с клавиатуры.
Выходные данные: упорядоченная по алфавиту последовательность слов выводится на
экран.
Текст программы.
Turbo Pascal
Program LexOrder;
Uses Crt;
Var Words
: Array[1..10] of String; {массив слов}
3
Tmp
: String;
i, j, NWords : Integer;
{Tmp - вспомогательная переменная}
{NWords - количество слов}
BEGIN
ClrScr;
Write('Количество слов в тексте - ');
ReadLn(NWords);
For i := 1 to NWords do
begin Write(i, '-ое слово : ');
ReadLn(Words[i])
end;
For i := 1 to NWords-1 do {лексикографическое упорядочение слов}
For j := i+1 to NWords do
If Words[i]>Words[j] then
begin
Tmp := Words[i]; Words[i]:=Words[j]; Words[j]:=Tmp
end;
WriteLn; WriteLn('О т в е т');
WriteLn('Лексикографически упорядоченный массив слов:');
For i := 1 to NWords do Write(Words[i], ' ');
WriteLn; ReadLn
END.
Задача №5 «Магический квадрат» (max 100 баллов)
Проверить, является ли заданная целочисленная матрица A(N, N) "магическим квадратом"
(это значит, что суммы чисел во всех её строках, всех столбцах и двух диагоналях одинаковы).
Требуется написать программу, которая решает названную задачу.
Исходные данные: N – количество строк (столбцов) матрицы, целочисленная матрица
A(N, N).
Выходные данные: на экран выводится сообщение ''Магический квадрат'' или ''Не
магический квадрат ''.
Turbo Pascal
Program MagicSquare;
Uses Crt;
Var A : Array [1..20, 1..20] of Integer;
i, j, N : Integer;
Standard, S : Integer; {Standard - сумма-эталон, S - текущая сумма}
Flag : Boolean;
{-------------------------------------}
Procedure InputOutput; {описание процедуры ввода-вывода матрицы}
Begin
ClrScr;
Write('Количество строк и столбцов - ');
ReadLn(N);
For i := 1 to N do
For j := 1 to N do
begin Write('A[' , i , ', ' , j , '] = ');
ReadLn(A[i, j])
end;
ClrScr;
WriteLn('Исходная матрица :'); WriteLn;
For i := 1 to N do
begin
For j := 1 to N do Write(A[i, j] : 5);
WriteLn
4
end; WriteLn
End; { of InputOutput }
{-------------------------------------------}
Procedure MagicOrNot(Var Flag : Boolean);
{описание процедуры, }
{в которой выясняется, является ли квадрат "магическим"}
{вычисление суммы элементов главной диагонали}
{в качестве эталонной суммы}
Standard:=0;
For i := 1 to N do Standard := Standard + A[i,i];
Flag:=TRUE; i:=1;
While (i<=N) and Flag do {вычисление сумм элементов строк}
begin
S:=0;
For j := 1 to N do S := S+A[i, j];
If S<>Standard then Flag := FALSE else i:=i+1
end;
j:=1;
While (j<=N) and Flag do {вычисление сумм элементов столбцов}
begin
S:=0;
For i := 1 to N do S:=S+A[i, j];
If S<>Standard then Flag := FALSE else j := j+1
end;
If Flag then
begin
S:=0; {вычисление суммы элементов побочной диагонали}
For i := 1 to N do S := S+A[i, N+1-i];
If S<>Standard then Flag := FALSE;
end;
End;
{--------------------------------------------------------}
BEGIN
InputOutput; {Вызов процедуры ввода-вывода }
MagicOrNot(Flag); {Вызов процедуры решения задачи }
If Flag then WriteLn('Это магический квадрат.')
else WriteLn('Это не магический квадрат.');
ReadLn
END.
Begin
Задача 6.
Задан числовой массив А(10). Определить, каких элементов больше в этом массиве:
положительных или отрицательных. Если их одинаковое количество, то выдать ответ «поровну».
Если таковых нет, то выдать ответ «нет»
Текст рабочей части программы без определения элементов массива
z:=0; p:=0; n:=0 {z- количество нулей, p и n соответственно положительных и отрицательных элементов}
for i:=1 to 10 do
begin
if a[i]>0 then p:=p+1;
if a[i] < 0 then n:=n+1;
if a[i] = 0 then z:=z+1;
end;
If p>n then Writeln(‘положительных больше’);
IF p<n then Writeln(‘положительных меньше’);
If (p=n) and (p<>0) then Writeln(‘поровну’);
If (p=n) and (p=0) then Writeln(‘нет’);
5
Задача 7 (а).
Задана точка с координатами (x, y) и треугольник с координатами вершин (x1, y1), (x2, y2),
(x3, y3). Определить, лежит ли точка внутри или вне треугольника.
Идея решения задачи следующая.
Соединим точку с координатами (x,y) отрезками с вершинами треугольника и подсчитаем сумму
площадей полученных треугольников.
Если сумма площадей полученных треугольников равна площади исходного треугольника, то
точка (x,y) лежит внутри треугольника.
Если сумма полученных треугольников больше суммы исходного треугольника, то точка (x,y)
лежит вне треугольника.
Опишем функции, которые можно использовать в алгоритме
function dlina (x,y,x1,y1:real):real; {вычисление длины отрезка}
Var s: real;
Begin
S:=(x-x1)*(x-x1) + (y-y1)*(y-y1)
Dlina:=sqrt(s)
End;
function ploshad (x1,y1,x2,y2,x3,y3:real):real; {вычисление площади треугольника }
Var a,b,c,d,p,s :real;
Begin
a:= dlina (x1,y1,x2,y2);
b:= dlina (x2,y2,x3,y3);
c:= dlina (x1,y1,x3,y3);
s:=p*(p-a)*(p-b)*(p-c);
ploshad:=sqrt(s);
End;
Задача 7 (б).
Для заданной строки символов проверить, является ли она палиндромом (симметричной с
точностью до пробелов и знаков препинаний) или нет.
Например, палиндромами являются цепочки:
АРГЕНТИНА МАНИТ НЕГРА
А РОЗА УПАЛА НА ЛАПУ АЗОРА
(Предполагается, что все буквы строки - прописные).
var s, s1:string;
i,k,n,m:integer;
begin
s1:=’’
for i:=1 то length(s) do
begin
if s[i]<>’ ‘ then s1:=s1+s[i]
end;
s:=s1;
{удаление из строки s пробелов }
readln(s);
{определение палиндрома}
n:=length(s);
k:=0;
m:=n div 2;
for i:=1 to m do
if s[i]<>s[n-i+1] then k:=1;
if k=0 then writeln('Да палиндром')
else writeln('Нет, не палиндром');
end.
6
Задача 8. «Превращение»
Необходимо представить некоторое целое положительное число N в виде сумме квадратов
двух целых положительных чисел P и Q (0<P<=Q). Это не всегда возможно. Если точного
разложения не существует, нужно подобрать такие P и Q, чтобы значение выражения |N–P2–Q2|
было минимальным. Если существует несколько вариантов разложения, минимизирующих
значение указанного выражения, то вывести вариант с меньшим Q.
Напишите программу, которая вводит с клавиатуры целое число N (1<=N<=106) и выводит на
экран целые значения P и Q.
Пример ввода:
Пример вывода:
14
2 3
Требуется выполнить двойной цикл по P и Q и выбрать числа P и Q, минимизирующие
указанное выражение, а для одинакового значения выражения – с меньшим Q. Так как N<=106, то
нужно рассматривать P и Q, не превышающие тысячи, т.е. внутренняя часть цикла выполняется
около 500 000 раз. Рекомендуется для P и Q использовать тип longint, чтобы не происходило
переполнение при возведении в квадрат.
var z,p,q,mind,minp,minq,maxp,d:longint;
begin
read(z);
mind:=1000000;
maxp:=trunc(sqrt(z));
for p:=1 to maxp do
for q:=p to maxp do
begin
d:=abs(z-p*p-q*q);
if (d<mind) or ((d=mind) and (minq>q)) then
begin
mind:=d;
minp:=p;
minq:=q;
end;
end;
writeln(minp,' ',minq);
end.
7
Задача 9. «Фигура»
Составить программу, которая выводит на экран фигуру (см.
рисунок), вычерчиваемую одним росчерком.
1 уровень: Размер изображения фиксирован.
2 уровень: Размер изображения можно менять. С клавиатуры
вводится размер меньшей окружности, остальные размеры вычисляются
в зависимости от него.
Фигура состоит из одной большой окружности, девяти малых (радиусы которых равны) и
18 линий (равных). Центр каждой из малых окружностей лежит на дуге большой окружности,
начиная от 0º, с шагом в 40º, они соприкасаются. Из центра каждой из девяти малых окружностей
выходит по 2 линии, которые соединяют центр данной окружности с центрами окружностей,
лежащих через 160º и 200º.
Для построения данной фигуры понадобится 1 цикл, от которого будет зависеть угол
наклона линий, а значит и их направление, а также – координаты центров малых окружностей,
следовательно и их местоположение. Центр вычисляется через косинус, синус и радиус, как и
угол между прямыми.
Uses Graph;
Var gd,gm,i,j: integer;
Begin
Gd:=Detect;
Gm:=0;
InitGraph(gd,gm,'C:/BP/BGI');
CIRCLE(320,240,100);
j:=4;
for i:=0 to 8 do begin
CIRCLE(320+round(100*cos(i*40*pi/180)),240round(100*sin(i*40*pi/180)),34);
LINE(320+round(100*cos(i*40*pi/180)),240round(100*sin(i*40*pi/180)),
320+round(100*cos(j*40*pi/180)),240round(100*sin(j*40*pi/180)));
j:=j+1;
end;
ReadLn;
CloseGraph;
end.
8
Задача 10. «Школа имени Джеймса Бонда»
Учащиеся этой школы должны сдавать зачет по прыжкам с тарзанки. Если, держась за тарзанку,
ученик прыгает, то он сначала опускается вниз, а затем по инерции поднимается вверх. Но
высота, на которую он поднимется, будет в K раз меньше, чем высота, с которой он опустился.
Будем считать, что ученик повис, если высота его очередного подъема не превышает 1.
Напишите программу, которая по длине веревки L и коэффициенту K считает количество
подъемов ученика до остановки. Например, пусть L=17, K=2, тогда ученик будет подниматься на
высоты 8.5, 4.25, 2.125, 1.0625, а затем остановится, таким образом получится 4 подъема.
Вводятся через пробел два целых числа L (1<=L<=109) и K (2<=K<=100).
Вывести одно число – количество подъемов.
Пример ввода:
Пример вывода:
17 2
4
var l,k:extended;
n:integer;
begin
read(l,k);
n:=0;
l:=l/k;
while l>1 do
begin
inc(n);
l:=l/k;
end;
writeln(n);
end.
Задача 11. «Вася у папы»
Вася у папы силён в математике, поэтому вместо того, чтобы слушать учителя, рисовал
числа в тетрадке в клеточку. Да не просто так рисовал, а определенным образом. Сначала он
поставил в клетку число 1. Затем справа от нее нарисовал число 2. Затем снизу от числа 2
написал число 3. Затем перешёл на клетку правее и продолжил увлекательное занятие, двигаясь
по столбцу вверх, пока число в этом столбце не стало выше
самого верхнего числа в предыдущем столбце. Затем он
перешёл на клетку правее и опять-таки продолжил
16 17
рисование чисел, начиная с 7, но только уже сверху вниз,
пока не нарисовал число, которое оказалось на одну клетку
6
7
15 18
ниже самого нижнего числа в предыдущем столбце. И так
1
2
5
8
14 19
далее. Вася не любил числа, заканчивающиеся нулем, и
пропускал их при рисовании. Первые его шесть
3
4
9
13 21
заполненных столбцов мы скопировали из его тетрадки и
привели здесь на рисунке. Так как Вася очень любит
11 12 22
математику, то он очень хочет узнать, какое же число будет
у него стоять в N-ом столбце в той строке, где стоит число 1.
23
Первые 6 таких чисел в этой строке видны на рисунке: 1, 2,
5, 8, 14, 19. Напишите программу, которая поможет Васе.
9
Вводится одно число N (1<=N<=106) – номер столбца.
Вывести N-ое число в строке, где стоит число 1.
Пример ввода:
Пример вывода:
5
14
Выявляется математическая зависимость в формируемой строке и вычисляется искомый
символ.
var n2,r,r1,k1:extended;
n:longint;
function kol0(b:extended):extended;
var s:string;
a:extended;
e:integer;
begin
str(b:0:0,s);
s:=copy(s,1,length(s)-1);
if length(s)=0 then
a:=0
else
val(s,a,e);
kol0:=a;
end;
begin
read(n);
n2:=n div 2;
r:=sqr(n-n2)+sqr(n2);
k1:=kol0(r);
while k1>0 do
begin
r1:=r;
r:=r1+k1;
k1:=kol0(r)-kol0(r1);
end;
writeln(r:0:0);
end.
Задача 12. «ДвоИчники»
В стране ДвоИчников вся информация записывается в двоичном коде. Палиндромом у
них тоже называется строка, которая читается одинаково слева направо и справа налево.
Например, 1001 – палиндром, 1010 – нет. Напишите программу, которая превращает любую
строку из 0 и 1 в палиндром, добавляя в нее минимальное количество новых символов.
Добавлять
новые
символы
можно
слева,
справа
и
внутрь
строки.
Вводится строка длиной не более 100 символов, состоящая только из 0 и 1.
Вывести в первой строке количество добавленных символов, во второй строке – получившийся
палиндром. Если существует несколько вариантов, вывести вариант, который идет раньше в
лексикографическом порядке.
10
Пример ввода:
1010
Пример вывода:
1
01010
Задача на динамическое программирование. Сначала необходимо построить таблицу T, в
которой в ячейке T[i,j] хранится минимальное количество добавляемых символов к строке s[i...j]
для получения палиндрома. T[i,j]=T[i+1,j-1], если s[i]=s[j], T[i,j]=min(T[i,j-1],T[i+1,j])+1 если
s[i]<>s[j]. Выполняя обратную трассировку по таблице T легко найти палиндром-результат.
"Жадное" частичное решение, выполняющее анализ строки одновременно слева и справа и
добавляющее в результат меньший из концов в случае несовпадения, дает 10 баллов.
var tbl : array[1..100,1..100] of integer;
s, r : string;
i,j,n,ir,jr : integer;
begin
readln(s);
n:=length(s);
for i:=1 to n do
tbl[i,i]:=0;
for i:=1 to n-1 do
if s[i]<>s[i+1]
then tbl[i,i+1]:=1
else tbl[i,i+1]:=0;
for i:=n-2 downto 1 do
for j:=1 to i do
begin
if s[j]=s[n-i+j]
then tbl[j,n-i+j]:=tbl[j+1,n-i+j-1]
else
if tbl[j+1,n-i+j]<tbl[j,n-i+j-1]
then tbl[j,n-i+j]:=tbl[j+1,n-i+j]+1
else tbl[j,n-i+j]:=tbl[j,n-i+j-1]+1;
end;
writeln(tbl[1,n]);
r:='';
for i:=1 to n+tbl[1,n] do
r:=r+' ';
i:=1;
j:=n;
ir:=1;
jr:=n+tbl[1,n];
while i<=j do
begin
if s[i]=s[j] then
begin
r[ir]:=s[i];
r[jr]:=s[j];
inc(ir);inc(i);
dec(jr);dec(j);
end
11
else
if (tbl[i+1,j]<tbl[i,j-1]) or ((tbl[i+1,j]=tbl[i,j-1])
and (s[i]<s[j]))
then
begin
r[ir]:=s[i];
r[jr]:=s[i];
inc(ir);inc(i);
dec(jr);
end
else
begin
r[ir]:=s[j];
r[jr]:=s[j];
inc(ir);
dec(jr);dec(j);
end;
end;
writeln(r);
end.
Задача 13. «Треугольник» (7-9 класс)
Даны действительные числа a, b, c. Определить, существует ли треугольник с такими
длинами сторон. Если существует, то какой: равносторонний, равнобедренный или произвольной
формы.
Входные данные.
Значения действительных чисел a,b,c ввести с клавиатуры после сообщения «Введи значения
сторон треугольника a, b, c».
Выходные данные.
Выводим на экран дисплея результат решения задачи с соответствующими сообщениями.
Пример ввода:
Пример вывода:
355
существует
равнобедренный
1 вариант (упрощенный).
Решение
{Определение возможности существования треугольника, стороны которого заданы целыми
значениями a, b, c.}
Program PP1;
Uses Crt;
Var a,b,c:integer;
k:boolean;
Begin
ClrScr;
Write ('Введи значения сторон треугольника через пробел: ');
12
Readln (a,b,c);
{Ввод числовых значений с клавиатуры}
{Логическое условие}
If (a+b>c) and (a+c>b) and (b+c>a) then
Writeln ('Треугольник существует') else
Writeln ('Треугольник не существует');
ReadKey;
End.
2 вариант.
Решение
{Определение возможности существования треугольника, стороны которого заданы целыми
значениями a, b, c. Если существует, то какой: равносторонний, равнобедренный или
произвольной формы.}
Program Card15;
Uses Crt;
Label 10;
Var a,b,c:real;
begin
ClrScr;
{}
WriteLn('Введи значения сторон треугольника a, b, c');
Read(a,b,c);
{}
if ((a+b)>c) and ((a+c)>b) and ((b+c)>a) then
WriteLn('Треугольник существует') else
begin
WriteLn('Треугольник не существует');
GoTo 10;
end;
if (a=b) and (a=c) and (b=c) then
begin
WriteLn('Треугольник равносторонний');
GoTo 10;
end;
if (a=b) or (a=c) or (b=c) then
begin
WriteLn('Треугольник равнобедренный');
GoTo 10;
end;
WriteLn('Треугольник произвольной формы');
10:ReadKey
end.
Задача 14. «Из пушки на Луну»
«Путь снаряда лежал между Землей и Луной. По мере того как снаряд удалялся от Земли,
земное притяжение уменьшалось, лунное же притяжение возрастало. В какой-то точке пути оба
притяжения – лунное и земное – должны были уравновеситься, и тогда снаряд должен был
потерять всякий вес. В этой точке равновесия притяжении всякое тело, не имеющее никакой
скорости и никакого двигателя, осталось бы навеки неподвижным, потому что оба светила
притягивали бы его с равной силой, и ничто не могло бы заставить его лететь в ту или другую
сторону.
Если сила толчка была рассчитана правильно, снаряд должен был достигнуть этой точки при
нулевой скорости, утратив какие бы то ни было признаки веса вместе со всеми находящимися в
нем предметами. Что же случилось бы после этого? Представлялись три возможности.
13
Либо снаряд, все же сохранивший некоторую скорость, пройдя точку равных притяжений,
упал бы на Луну, так как лунное притяжение возобладало бы над земным.
Либо снаряду не хватило бы скорости для достижения нейтральной точки, и тогда он упал бы
обратно на Землю, так как земное притяжение возобладало бы над лунным.
Либо, наконец, двигаясь с достаточной скоростью для достижения нейтральной точки, но
недостаточной, чтобы перейти за нее, он навеки остановился бы, паря на этой линии, как
легендарный Магометов гроб, между зенитом и надиром».
Жюль Верн «Вокруг Луны»
Напишите программу, которая определяет, сила притяжения Земли или Луны сильнее
действует на снаряд, находящийся в точке (X,Y). Центр Земли находится в точке с координатами
(0, 0), центр Луны в точке с координатами (384000, 0), масса Земли в 81 раз больше массы Луны.
Сила взаимного притяжения двух тел с массами m1 и m2, находящихся на расстоянии R, может
быть вычислена по формуле F=G*m1*m2/R2, где G – гравитационная постоянная, равная 6.673E11.
Вводятся через пробел два целых числа X (0 < X < 384000) и Y (–100000 < Y < 100000).
Вывести сообщение “Earth”, если сила притяжения Земли больше, или “Moon”, если больше
сила притяжения Луны, или “Equal”, в случае равенства сил. Кавычки в сообщении не выводятся.
Пример ввода:
100000 0
Пример вывода:
Earth
Программа:
var x,y,d:extended;
begin
read(x,y);
d:=81.0/(sqr(x)+sqr(y))-1.0/(sqr(384000-x)+sqr(y));
if d>0 then writeln('Earth')
else if d<0 then writeln('Moon')
else writeln('Equal');
end.
Задача 16. «Превращение» (7-9 класс)
Возьмем какое-нибудь натуральное число N. Будем изменять его следующим образом: если
число четное, то разделим его на 2, если нечетное, прибавим 1. После нескольких таких
изменений мы всегда получаем число 1. Например, из числа 11 получается число 12, затем 6, 3, 4,
2 и, наконец, 1. Таким образом, для получения 1 из 11 нужно проделать 6 изменений.
Напишите программу, которая вводит с клавиатуры натуральное число N (1<=N<=109) и
выводит на экран количество изменений данного числа до получения 1.
Пример ввода:
11
Пример вывода:
6
14
Программа:
var n:longint;
k:integer;
begin
readln(n);
k:=0;
while n<>1 do
begin
if n mod 2=1 then
n:=n+1
else
n:=n div 2;
inc(k);
end;
writeln(k);
end.
Задача 17. «Считаем ворон» (7-9 класс)
Дано число К (К<100). Напечатать фразу вида «К ворон», где К – выражено прописью
данного числа: двадцать одна ворона, тридцать ворон и т.д.
Пример ввода:
3
Пример вывода:
три вороны
var k,a,b: integer;
begin
writeln ('введите число ворон'); readln (k);
a:=k div 10;
b:=k mod 10;
if (a=1) and (b=0) then write ('десять ');
if (a=1) and (b<>0) then begin
case b of
1:write ('один');
2:write ('две');
3:write ('три');
4:write ('четыр');
5:write ('пят');
6:write ('шест');
7:write ('сем');
8:write ('восем');
9:write ('девят');
end;
write ('надцать ');
end
else
begin
Case a of
2:write ('двадцать ');
3:write ('тридцать ');
4:write ('сорок ');
5:write ('пятьдесят ');
6:write ('шестьдесят ');
7:write ('семьдесят ');
8:write ('восемьдесят ');
9:write ('девяносто ');
end;
15
Case b of
1:write ('одна ');
2:write ('две ');
3:write ('три ');
4:write ('четыре ');
5:write ('пять ');
6:write ('шесть ');
7:write ('семь ');
8:write ('восемь ');
9:write ('девять ');
end;
end;
write ('ворон');
if a<>1 then
case b of
1:write ('а');
2:write ('ы');
3:write ('ы');
4:write ('ы');
end;
end.
Задача 18. «Разведчики тоже ошибаются» (9-11 кл)
Штирлиц регулярно получал шифровки от пастора Шлага из Берна, но расшифровать их
удавалось не всегда. Дело в том, что пастор постоянно ошибался, составляя шифровку.
Информацию он получал каждый день, проходя мимо окон явочной квартиры и наблюдая за
окном. Сигналом служил цветок на окне. Если окно выглядело также как и в предыдущий день,
пастору нужно вписать в шифровку 1, если вид окна изменялся (цветок появлялся или наоборот
исчезал), то передавать следовало 0. В первый день наблюдения за окном цветка на нём не было.
Чтобы избавить пастора от ошибок при составлении шифровки, а Штирлица от проблем при
расшифровке программисты Центра разработали программу, которая составляла шифровку, имея
информацию о наличии или отсутствии цветка на окне за необходимый период. Период, за
который пастор мог составлять шифровку, не превышал 100 дней. Представьте возможный
вариант такой программы. Для обозначения состояния окна используйте обозначения: 1 – есть
цветок; 0 – цветка нет.
Пример ввода:
10010111
Пример вывода:
11011100
Пример программы:
var s
: string;
p,q : char;
i
: integer;
begin
readln(s);
p:='0';
for i:=1 to length(s) do
begin
q:=s[i];
if p<>q then s[i]:='1'
else s[i]:='0';
p:=q;
end;
writeln(s);
end.
16
Задача 19. «Зачем нужна математика» (9-11 кл)
Сотрудники солидной фирмы Matland, занимающейся серъёзными научными разработками,
обязаны были отлично знать математику. Особенно серьезные требования предъявлялись к
устному счету. Руководство фирмы использовало различные методы для развития
математических способностей сотрудников. Например, чтобы получить свою зарплату работник
предприятия должен был вводить числовой пароль. Причем пароль менялся в зависимости от
суммы, которая начислялась работнику, и равнялся количеству разложений этой суммы на
простые слагаемые.
Например, чтобы поручить заработную плату в 11 рублей работник должен был определить,
что для этого числа существует 6 различных разложений на простые множители: 11=11,
11=2+2+7, 11=3+3+5, 11=2+2+2+5, 11=2+3+3+3, 11=2+2+2+2+3. Значит, пароль для получения
денег равен 6.
Напишите программу, которая поможет сотрудникам фирмы получать зарплату. Она должна
вводить с клавиатуры заработную плату сотрудника (натуральное число) и выводить на экран
пароль для получения денег в кассе. Заработная плата сотрудников этого предприятия не
превышает 5000 руб.
Пример ввода:
11
Пример вывода:
6
Программа:
{Длинная арифметика, храним по 4 цифры в элементе массива}
const maxlen=12;
type number=array [0..maxlen] of integer;
pnumber=^number;
procedure add(var n1,n2,nr:number);
var i,p:integer;
begin
p:=0;
for i:=0 to maxlen do
begin
p:=p+n1[i]+n2[i];
nr[i]:=p mod 10000;
p:=p div 10000;
end;
end;
procedure setval(var n:number; v:integer);
var i:integer;
begin
for i:=1 to maxlen do n[i]:=0;
n[0]:=v;
end;
procedure print(var n:number);
var i,k:integer;
begin
k:=maxlen;
while (k>0) and (n[k]=0) do dec(k);
write(n[k]);
for i:=k-1 downto 0 do
if n[i]<10 then write('000',n[i])
else if n[i]<100 then write('00',n[i])
17
else if n[i]<1000 then write('0',n[i])
else write(n[i]);
writeln;
end;
function isprime(n:longint):boolean;
var i:longint;
begin
i:=2;
while i*i<=n do
begin
if n mod i=0 then
begin
isprime:=false;
exit;
end;
inc(i);
end;
isprime:=true;
end;
{Динамическое программирование}
var q:array [2..5000] of pnumber;
one:number;
procedure init;
var i:integer;
begin
for i:=2 to 5000 do
begin
new(q[i]);
setval(q[i]^,0);
end;
setval(one,1);
end;
procedure fill;
var i,j:integer;
begin
for i:=2 to 5000 do
if isprime(i) then
begin
add(q[i]^,one,q[i]^);
for j:=i+2 to 5000 do
add(q[j]^,q[j-i]^,q[j]^);
end;
end;
var i:integer;
begin
init;
fill;
readln(i);
print(q[i]^);
end.
18
Задача 20. «Преобразования» (9-11 кл)
Возьмем последовательность из одного бита «0». Далее выполняем N следующих шагов.
На каждом шаге бит «0» заменяем на два бита «10», а бит «1» на два бита «01». После
выполнения первого шага из последовательности «0» получается последовательность «10», после
второго - «0110», после третьего - «10010110», после четвертого - «0110100110010110», и так
далее. Напишите программу, которая определяет количество соседних битов «00» в
последовательности после N-го шага.
Вводится одно целое число N (1<=N<=1000).
Вывести количество соседей «00» после N-го шага.
Пример ввода:
4
Пример вывода:
2
Решение:
Задача заключается в выводе рекуррентного соотношения. Рассмотрим двух соседей 00, на
следующем шаге эти соседи исчезнут 1010, а еще через шаг пара 00 появится снова 01100110.
Кроме того каждая 1 через два шага порождает соседей 00. Количество 1 на каждом шаге
удваивается. Окончательно формула выглядит так S0=0, S1=0, Sk=Sk-2+2k-2. Для вычислений
потребуется длинная арифметика (только операция сложения и печать) Частичное решение выполнение указанных преобразований с помощью. Правильная формула с использованием
extended вместо длинной арифметики.
Пример программы:
type lint = record
len:integer;
dgt:array[1..1000] of char;
end;
procedure add(var a, b, c : lint);
var p, i : integer;
begin
p:=0;
i:=1;
while (i<=a.len) or (i<=b.len) do
begin
if (i<=a.len) then p:=p+ord(a.dgt[i])-ord('0');
if (i<=b.len) then p:=p+ord(b.dgt[i])-ord('0');
c.dgt[i]:=chr((p mod 10)+ord('0'));
p:=p div 10;
inc(i);
end;
if p>0 then
begin
c.dgt[i]:=chr(p+ord('0'));
inc(i);
end;
c.len:=i-1;
end;
procedure init(var a : lint; b : integer);
begin
a.len:=1;
19
a.dgt[1]:=chr(b+ord('0'));
end;
procedure print(var a : lint);
var i : integer;
begin
for i:=a.len downto 1 do
write(a.dgt[i]);
writeln;
end;
var st2, f1, f2, f3 : lint;
n, i : integer;
begin
read(n);
init(st2,1);
init(f1,0);
init(f2,0);
if n<=2 then writeln('0')
else
begin
for i:=3 to n do
begin
add(st2,f1,f3);
add(st2,st2,st2);
f1:=f2;
f2:=f3;
end;
print(f3);
end;
end.
Задача 21. «Палиндром» (9-11 кл)
Палиндромом называется строка, которая читается одинаково слева направо и справа налево.
Например, 1001 – палиндром, 1010 – нет. Напишите программу, которая превращает любую
строку из 0 и 1 в палиндром, добавляя в нее минимальное количество новых символов.
Добавлять новые символы можно слева, справа и внутрь строки.
Вводится строка длиной не более 100 символов, состоящая только из 0 и 1.
Вывести в первой строке количество добавленных символов, во второй строке – получившийся
палиндром. Если существует несколько вариантов, вывести вариант, который идет раньше в
лексикографическом порядке.
Пример ввода:
1010
Пример вывода:
1
01010
Задача на динамическое программирование. Сначала необходимо построить таблицу T, в которой
в ячейке T[i,j] хранится минимальное количество добавляемых символов к строке s[i...j] для
получения палиндрома. T[i,j]=T[i+1,j-1], если s[i]=s[j], T[i,j]=min(T[i,j-1],T[i+1,j])+1 если
s[i]<>s[j]. Выполняя обратную трассировку по таблице T легко найти палиндром-результат.
20
Пример программы:
var tbl : array[1..100,1..100] of integer;
s, r : string;
i,j,n,ir,jr : integer;
begin
readln(s);
n:=length(s);
for i:=1 to n do
tbl[i,i]:=0;
for i:=1 to n-1 do
if s[i]<>s[i+1]
then tbl[i,i+1]:=1
else tbl[i,i+1]:=0;
for i:=n-2 downto 1 do
for j:=1 to i do
begin
if s[j]=s[n-i+j]
then tbl[j,n-i+j]:=tbl[j+1,n-i+j-1]
else
if tbl[j+1,n-i+j]<tbl[j,n-i+j-1]
then tbl[j,n-i+j]:=tbl[j+1,n-i+j]+1
else tbl[j,n-i+j]:=tbl[j,n-i+j-1]+1;
end;
writeln(tbl[1,n]);
r:='';
for i:=1 to n+tbl[1,n] do
r:=r+' ';
i:=1; j:=n; ir:=1; jr:=n+tbl[1,n];
while i<=j do
begin
if s[i]=s[j] then
begin
r[ir]:=s[i]; r[jr]:=s[j];
inc(ir); inc(i); dec(jr); dec(j);
end
else
if (tbl[i+1,j]<tbl[i,j-1]) or ((tbl[i+1,j]=tbl[i,j-1])
and (s[i]<s[j]))
then
begin
r[ir]:=s[i]; r[jr]:=s[i];
inc(ir); inc(i); dec(jr);
end
else
begin
r[ir]:=s[j]; r[jr]:=s[j];
inc(ir); dec(jr); dec(j);
end;
end;
writeln(r);
end.
21
22. «Превращение» (7-11 кл)
Необходимо представить некоторое целое положительное число N в виде сумме квадратов
двух целых положительных чисел P и Q (0<P<=Q). Это не всегда возможно. Если точного
разложения не существует, нужно подобрать такие P и Q, чтобы значение выражения |N–P2–Q2|
было минимальным. Если существует несколько вариантов разложения, минимизирующих
значение указанного выражения, то вывести вариант с меньшим Q.
Напишите программу, которая вводит с клавиатуры целое число N (1<=N<=106) и выводит на
экран целые значения P и Q.
Пример ввода:
Пример вывода:
14
23
Решение
Требуется выполнить двойной цикл по P и Q и выбрать числа P и Q, минимизирующие
указанное выражение, а для одинакового значения выражения – с меньшим Q. Так как N<=106,
то нужно рассматривать P и Q, не превышающие тысячи, т.е. внутренняя часть цикла
выполняется около 500 000 раз. Рекомендуется для P и Q использовать тип longint, чтобы не
происходило переполнение при возведении в квадрат.
Программа:
var z,p,q,mind,minp,minq,maxp,d:longint;
begin
read(z);
mind:=1000000;
maxp:=trunc(sqrt(z));
for p:=1 to maxp do
for q:=p to maxp do
begin
d:=abs(z-p*p-q*q);
if (d<mind) or ((d=mind) and (minq>q)) then
begin
mind:=d;
minp:=p;
minq:=q;
end;
end;
writeln(minp,' ',minq);
end.
23. «Сортировка» (9-11 кл)
Напишите программу, которая вводит с клавиатуры строку длиной от 1 до 25 символов,
состоящую из прописных латинских букв, и выводит на экран минимальное количество обменов,
которые необходимо сделать в этой строке, чтобы отсортировать буквы строки в алфавитном
порядке. Обмен – это перестановка двух букв. Например, чтобы отсортировать буквы строки
BAZAR, нужно сделать 3 обмена. Сначала можно поменять местами 3 и 5 букву (BARAZ), затем
3 и 4 буквы (BAARZ), и, наконец, 1 и 3 буквы (AABRZ).
Пример ввода:
BAZAR
Пример вывода:
3
Выполняем рекурсивный перебор всех вариантов обмена.
22
Программа: var st:string; ss:string; n:integer;
procedure sortstr(var s:string);
{ сортировка строки методом вставок }
var i,j:integer;
c:char;
begin
for i:=1 to length(s) do
begin
j:=i-1;
while j>=1 do
begin
if s[j+1]<s[j] then
begin
c:=s[j+1];
s[j+1]:=s[j];
s[j]:=c;
end
else
break;
dec(j);
end;
end;
end;
function nobmen(from:integer):integer;
{ минимальное количество обменов }
var i,j,o,om:integer;
ch:char;
lc:set of 'A'..'Z';
begin
{ символы от 1 до from уже стоят на своих местах }
nobmen:=0;
for i:=from+1 to n do
if (st[i]<>ss[i]) then
begin
om:=100;
lc:=[];
for j:=i+1 to n do
{ подбираем символ, который должен стоять в позиции i
нужно рассмотреть все варианты,
не рассматриваем варианты, эквивалентные предыдущим }
if (st[j]=ss[i]) and (st[j]<>ss[j]) and not (ss[j] in lc) then
begin
include(lc,ss[j]);
ch:=st[i]; { обмен }
st[i]:=st[j];
st[j]:=ch;
o:=1+nobmen(i);
ch:=st[i]; { обратный обмен }
st[i]:=st[j];
st[j]:=ch;
if om>o then om:=o; { если лучше, то запомним }
end;
nobmen:=om;
exit;
end;
end;
begin
writeln (‘Введите строку’);
readln(st);
ss:=st;
sortstr(ss);
n:=length(st);
writeln(nobmen(0));
end.
23
24. «Игра» (9-11 кл)
Двое играют в следующую игру. Сначала с помощью компьютера генерируется случайное
целое число N0, состоящее из двух или более цифр. Затем игроки ходят по очереди, соблюдая
следующие правила. Игрок, делающий i-ый ход, должен назвать новое число Ni, строго меньшее
числа Ni-1, но большее или равное сумме цифр числа Ni-1. Если игрок не может сделать ход по
правилам, то он проигрывает. Например, пусть N0=98. Первый игрок должен назвать число от 17
до 97. Если он назовет 17, то второй игрок назовет 8 и выиграет. Если он назовет 19, то второй
игрок должен будет выбрать число от 10 до 18, и какое бы число второй игрок не назвал, первый
игрок сможет назвать 9 и выиграть.
Напишите программу, которая вводит с клавиатуры натуральное число N0 (10<=N<10101)
и выводит на экран число N1 – ход, который позволит выиграть первому игроку при
безошибочной игре противников. Если выигрышный ход не существует, то программа должна
вывести 0.
Пример ввода:
98
Пример вывода:
19
Решение задачи требует математических рассуждений. В указанном диапазоне
существуют три числа N, а именно 19 (минимальное число с суммой цифр 10), 299 (минимальное
число с суммой цифр 20) и 3999999999999999999999999999999999 (минимальное число с
суммой цифр 300), которые являются проигрышными для игрока, делающего первый ход.
Принцип рассуждения показан в задаче. Например, для числа 299 следующее число нужно
выбирать в диапазоне от 20 до 298. Независимо от выбора следующий игрок может назвать число
19. Если начальное число N отличается от указанных чисел, то в качестве выигрышного хода
нужно выбрать одно из этих чисел в зависимости от суммы цифр числа N.
Программа:
var s:string;
ns,i:integer;
begin
readln(s);
ns:=0;
for i:=1 to length(s) do
ns:=ns+(ord(s[i])-ord('0'));
if (s='19') or (s='299') or
(s='3999999999999999999999999999999999') then
writeln('0')
else if ns<=9 then
writeln('9')
else if ns<=19 then
writeln('19')
else if ns<=299 then
writeln('299')
else
writeln('3999999999999999999999999999999999');
end.
24
25. «Водопой» (9-11)
В шахматной стране кони пасутся на клеточном поле, размером NxM (2 ≤ N, M ≤ 250) На
поле пасется Q (0 ≤ Q ≤ 10000) коней в различных клетках. На водопой кони собираются в одной
из клеток поля, заранее известной. Кони перемещаются по полю шагами, совпадающими с ходом
обыкновенного шахматного коня. Длина пути каждого коня до водопоя определяется как
количество шагов. Определить минимальное значение суммы длин путей коней до водопоя или,
если собраться коням у водопоя невозможно, то сообщить об этом. Сбор невозможен, если хотя
бы один из коней не может попасть к водопою.
Входные данные:
В первой строке входного файла находится 5 чисел, разделенных пробелом: N, M, S, T, Q.
N, M – размеры поля (отсчет начинается с 1); S, T – координаты клетки - водопоя (номер
строки и столбца соответственно), Q – количество коней на поле. И далее Q строк по два
числа – координаты каждого коня.
Выходные данные:
В выходной файл выводится одно число –минимальное значение суммы длин путей или –1, если
сбор невозможен.
Пример ввода:
4
2
3
3
Пример вывода:
4 1 1 3
3
2
3
6
5 5 3 4 0
Программа:
0
Var
sum, n, m, s, t, q : Longint;
a : Array[1..250, 1..250] Of Byte;
Procedure Init;
Begin
Assign(input, 'input.txt');
ReSet(input);
Assign(output, 'output.txt');
ReWrite(output);
ReadLn(n, m, s, t, q);
End;
Function Max(a, b : Integer) : Integer;
Begin
If a>b Then Max:=a Else Max:=b;
End;
Function Min(a, b : Integer) : Integer;
Begin
If a<b Then Min:=a Else Min:=b;
End;
function test(a1, b : integer) : boolean;
begin
if (a1<=n) and (a1>=1) and (b<=m) and (b>=1) and (a[a1, b]<>0) then
test:=true else test:=false;
end;
Procedure seta(s, t, n : Integer);
Begin
25
a[s, t]:=n;
if test(s+2,
if test(s+2,
if test(s-2,
if test(s-2,
if
if
if
if
End;
test(s+1,
test(s+1,
test(s-1,
test(s-1,
t-1)
t+1)
t+1)
t-1)
then
then
then
then
seta(s+2,
seta(s+2,
seta(s-2,
seta(s-2,
t-1,
t+1,
t+1,
t-1,
n+1);
n+1);
n+1);
n+1);
t-2)
t+2)
t+2)
t-2)
then
then
then
then
seta(s+1,
seta(s+1,
seta(s-1,
seta(s-1,
t-2,
t+2,
t+2,
t-2,
n+1);
n+1);
n+1);
n+1);
Procedure Run;
Begin
seta(s, t, 1);
seta(s+1, t, 3);
End;
Procedure Done;
var
x, y : integer;
Begin
For y:=1 To 127 Do
Begin
For x:=1 To 127 Do
If a[x, y]<>0 Then Write(a[x, y], ' ') Else Write(' ');
Writeln;
End;
WriteLn(Sum);
Close(input);
Close(output);
End;
Begin
Init;
Run;
Done;
End.
26. «Дружественные числа» (7-11 кл)
Будем называть два числа дружественными, если они состоят из одних и тех же цифр.
Например, числа 1132 и 32321 является дружественными, а 12 и 123 нет (в первом числе нет
цифры 3). Напишите программу, определяющую являются ли два заданных числа
дружественными.
В первой строке входного файла содержатся два целых числа A и B, разделенных одним
пробелом, (0<A<109, 0<B<109).
В выходной файл вывести сообщение YES, если A и B являются дружественными, или NO,
если не являются.
Пример ввода:
1132 32321
Пример вывода:
YES
26
Программа:
type digits=set of 0..9;
var
a,b:longint;
da,db:digits;
procedure dig(n:longint;var d:digits);
begin
d:=[];
while n>0 do
begin
include(d, n mod 10);
n:=n div 10;
end;
end;
begin
assign(input,'input.txt');
reset(input);
assign(output,'output.txt');
rewrite(output);
read(a,b);
dig(a,da);
dig(b,db);
if da=db then
writeln('YES')
else
writeln('NO');
close(input);
close(output);
end.
27.
«Кто похвалит меня лучше всех» (9-11 кл)
Леночка на свой день рождения решила угостить ребят из своей школы конфетами. Для
этого она попросила маму купить N вкусных конфет и решила, что первый похваливший её в
этот день школьник должен получить наибольшее количество вкусных конфет, а каждый
последующий — строго меньше, чем предыдущий (Леночка любила, чтобы на неё сразу
обращали внимание). Количество конфет, которым Леночка могла угостить, зависело от
предыдущего поведения школьника по отношению к Леночке, а также от волшебных слов,
произносимых им. Например, 6 конфет могут быть в результате распределены по одной из
следующих четырех схем: 3+2+1 (три конфеты первому из похваливших её школьников, две —
второму и одну — третьему), 4+2, 5+1 и 6 (все конфеты съедает счастливчик, похваливший
Леночку первым).
Напишите программу, определяющую, каким количеством различных способов Леночка может
распределить принесенное лакомство среди школьников.
Входные данные:
Входной файл содержит одно целое число N — количество купленных конфет (0N225).
Выходные данные:
Выходной файл должен содержать одно целое число, равное количеству возможных
распределений конфет.
27
Пример ввода:
6
Пример вывода:
4
Программа:
var n,reshen:integer;
Procedure init;
var f:text;
begin
assign(f,'c.in');
reset(f);
read(f,n);
close(f)
end;
Procedure Outt;
var f:text;
begin
assign(f,'c.out');
rewrite(f);
write(f,reshen);
close(f)
end;
Procedure konfeta(Sdelan, delta:integer);
var m:integer;
begin
m:=1;
while (n-delta)>delta+m do
begin
konfeta ((Sdelan+delta),delta+m);
inc(m);
end;
if (n-delta)=delta+m then inc(reshen);
end;
begin
init;
reshen:=0;
konfeta (0,0);
outt;
end.
28. «Закраска прямой» (9-11 кл)
Определение: Интервал прямой с целочисленными координатами [a,b) содержит левую
границу – точку а, и не содержит правую границу – точку b.
Интервал от 0 до 1.000.000.000 выкрасили в белый цвет. Затем было выполнено N
(1<=N<=100) операций перекрашивания. При каждой операции цвета в интервале, границы
которого задаются, меняются на противоположный (белый на черный, черный на белый).
Написать программу поиска самого длинного интервала белого цвета после заданной
последовательности операций перекрашивания.
Входные данные:
Входной файл содержит в первой строке число N и затем N строк с границами
интервалов.
Выходные данные:
В выходной файл выводится одно число – длина самого большого белого интервала.
28
Пример ввода:
4
20 50
10 35
40 90
100 1000000000
Программа:
Пример вывода:
15
const max = 1000000000;
maxn = 110;
var a : array[0..2 * maxn + 1] of longint;
n : integer;
procedure readData;
var i : integer;
begin
read (n);
for i := 1 to n do read (a[2 * i - 1], a[2 * i]);
a[0] := 0;
a[2 * n + 1] := 1000000000;
end;
procedure sort;
var i, j : integer;
temp : longint;
begin
for i := 1 to 2 * n - 1 do
for j := i + 1 to 2 * n do
if a[i] > a[j] then
begin
temp := a[i];
a[i] := a[j];
a[j] := temp;
end;
end;
procedure solve;
var max, cur : longint;
i : integer;
begin
sort;
max := 0;
cur := 0;
for i := 0 to 2 * n do
begin
if not odd (i) then cur := cur + a[i + 1] - a[i];
if (not odd (i)) and (cur > max) then
max := cur
else
begin
if odd (i) and (a[i + 1] - a[i] <> 0) then cur := 0;
end;
end;
writeln (max);
end;
begin
assign (input, 'input.txt'); reset (input);
assign (output, 'output.txt'); rewrite (output);
readData;
solve;
close (input);
close (output);
end.
29
29. «Простые» числа (7-11 кл.)
Дан набор различных натуральных чисел. Будем называть число «простым для заданного
набора», если число не делится ни на одно из чисел набора, кроме самого себя.
Во входном файле в первой строке содержится целое число N (1<=N<=100)– количество чисел
в наборе. Во второй строке файла содержатся N различных целых чисел от 1 до 1000000,
разделенных пробелами.
В выходной файл вывести «простые для заданного набора» числа, разделяя числа одним
пробелом. Числа выводятся в том порядке, в котором они шли во входном файле.
Входной файл INPUT.TXT
Выходной файл OUTPUT.TXT
6
5 3 8
10 5 3 15 6 8
var
N,i,j:integer;
A:array [1..100] of longint;
flg:boolean;
begin
read(N);
for i:=1 to N do
read(A[i]);
for i:=1 to N do
begin
flg:=true;
for j:=1 to N do
if (i<>j) and (A[i] mod A[j]=0)
then
flg:=false;
if flg
then
write(A[i]);
end;
end.
30
«Иван - царевич» ( 7-11 кл.)
30.
Было у царя три сына. Двоих царь удачно женил на боярской да купеческой дочерях, а с
младшим Иваном всё никак не ладилось. То в болоте стрела увязнет, а то и вовсе у лягушки
окажется. Пока царевич эту стрелу отыщет, время-то бежит. Царь-то пока сын стрелы ищет,
успел и науки всякие изучить и решил применить научный подход к поиску невесты сыну.
Сказал он ему теперь пускать за один-то раз не одну стрелу, а сразу несколько. При этом царь
задавал сыну следующие условия: Первую-то стрелу можно пускать куда глаза глядят, а вот
последующие стрелы должны отклоняться от первоначального направления строго на
заданный царем угол отклонения стрелы (0<α<180). При этом для экономии стрел царь
категорически запретил Ивану-царевичу пускать стрелы повторно в одном и том же
направлении.
Написать программу, которая по заданному царем углу отклонения стрелы определит
максимальное количество стрел, которые может пустить Иван-царевич за один раз, соблюдая
требования царя.
Пример ввода:
Пример вывода:
30
12
var
i,k,ugol,b: integer;
strela: array[0..359] of integer;
begin
readln (ugol);
strela[0]:= 1;
b:=ugol;
while strela[ugol] = 0 do
begin
strela[ugol]:= 1;
ugol:= (ugol+ b) mod 360;
end;
k:= 0;
for i:=0 to 359 do
begin
if strela[i]=1 then k:=k+1;
end;
writeln(k);
end.
31
31. «Остаток» (7-11 кл)
На доске подряд выписаны натуральные числа от 1 до n (n<1 000 000 000). Сначала с доски
стерли все нечетные числа. Из оставшихся чисел стирают все числа, оказавшиеся на четных
местах. Затем снова стирают все числа, оказавшиеся на нечетных местах, и так далее, пока не
останется одно число. Какое?
Пример ввода:
Пример вывода:
6
6
100
86
var
n,a,d:integer;
k:longint;
begin
readln(n);
a:=1;
d:=1;
k:=n;
while k > 1 do
begin
a:=a+d;
d:=d*2;
k:=k div 2;
if k > 1 then
begin
d:= d*2;
k:=(k + 1) div 2;
end;
end;
writeln(a);
end.
32
32. «Плоскость» (7-8 кл.)
Даны действительные числа x, y (x*y<>0.). Необходимо определить расположение точки с
координатами (x, y) на координатной плоскости и вывести на печать номер четверти
координатной плоскости, в которой находится эта точка.
Пример ввода:
Пример вывода:
12
1
В решении задачи необходимо предусмотреть фильтр, отсекающий нулевые значения: (x<>0)
and (y<>0).
Логические условия для определения расположения точки на координатной плоскости:
if
if
if
if
(x>0)
(x<0)
(x<0)
(x>0)
and
and
and
and
(y>0)
(y>0)
(y<0)
(y<0)
then
then
then
then
p:=1;
p:=2;
p:=3;
p:=4;
Программа:
Program Card16;
Uses Crt;
Var x,y:real;
p:byte;
begin
ClrScr;
{}
Randomize;
WriteLn('Исходные значения чисел x, y');
{Фильт, отсекающий нулевые значения x, y}
repeat
x:=20*Random-20*Random;
y:=20*Random-20*Random;
until (x<>0) and (y<>0);
WriteLn(x:8:3,y:8:3);
{Логические условия решения задачи}
if (x>0) and (y>0) then p:=1;
if (x<0) and (y>0) then p:=2;
if (x<0) and (y<0) then p:=3;
if (x>0) and (y<0) then p:=4;
WriteLn('Точка лежит в',p:3,' четверти');
ReadKey
end.
33
33. «Обмен» (9-11 кл.)
Напишите программу, которая вводит с клавиатуры строку длиной от 1 до 25 символов,
состоящую из прописных латинских букв, и выводит на экран минимальное количество обменов,
которые необходимо сделать в этой строке, чтобы отсортировать буквы строки в алфавитном
порядке. Обмен – это перестановка двух букв. Например, чтобы отсортировать буквы строки
BAZAR, нужно сделать 3 обмена. Сначала можно поменять местами 3 и 5 букву (BARAZ), затем
3 и 4 буквы (BAARZ), и, наконец, 1 и 3 буквы (AABRZ).
Пример ввода:
BAZAR
Пример вывода:
3
var st:string;
ss:string;
n:integer;
procedure sortstr(var s:string);
{ сортировка строки методом вставок }
var i,j:integer;
c:char;
begin
for i:=1 to length(s) do
begin
j:=i-1;
while j>=1 do
begin
if s[j+1]<s[j] then
begin
c:=s[j+1];
s[j+1]:=s[j];
s[j]:=c;
end
else
break;
dec(j);
end;
end;
end;
function nobmen(from:integer):integer;
{ минимальное количество обменов }
var i,j,o,om:integer;
ch:char;
lc:set of 'A'..'Z';
begin
{ символы от 1 до from уже стоят на своих местах }
nobmen:=0;
for i:=from+1 to n do
if (st[i]<>ss[i]) then
begin
om:=100;
lc:=[];
for j:=i+1 to n do
{ подбираем символ, который должен стоять в позиции i
34
нужно рассмотреть все варианты,
не рассматриваем варианты, эквивалентные предыдущим }
if (st[j]=ss[i]) and (st[j]<>ss[j]) and not (ss[j] in lc)
then
begin
include(lc,ss[j]);
ch:=st[i]; { обмен }
st[i]:=st[j];
st[j]:=ch;
o:=1+nobmen(i);
ch:=st[i]; { обратный обмен }
st[i]:=st[j];
st[j]:=ch;
if om>o then om:=o; { если лучше, то запомним }
end;
nobmen:=om;
exit;
end;
end;
begin
readln(st);
ss:=st;
sortstr(ss);
n:=length(st);
writeln(nobmen(0));
end.
34. «Система счисления с максимальной суммой цифр» (9-11 кл)
Дано натуральное число N. Найти систему счисления с основанием k=2..16 с наибольшей
суммой цифр (суммы цифр рассматривается в десятеричной арифметике) в представлении числа
N. Если систем счисления с таким максимальным свойством несколько, то вывести все
значения оснований с таким максимальным свойством.
Формат входных данных
Во входном текстовом файле в первой строке находится натуральное число N (N≤231-1).
Формат выходных данных
На выходе программы выводится одно или несколько значений оснований (2≤K≤16), и,
соответственно, сумма цифр.
Пример входного и выходного файлов
Пример входного файла
21
100
Пример выходного файла
Основания 11,Сумма 11
Основания 13,15,Сумма 16
35
Код программы (Pascal)
Uses crt;
const
nmax=10000000;
var
i,v,N,m,j, maximum, summacifr, osnovanie :longint;
a:array[1..10000] of longint; c:array [2..16] of longint;
begin
clrscr;
write('Vvodim chislo'); ReadLn(N); summacifr:=0; writeln('Predstavlenija');
for m:=2 to 16 do
begin
write(m); i:=0; v:=N;
While v>0 do
begin
inc(i);
a[i]:=v mod m;
v:=v div m
end; readln;
for j:=i downto 1 do
begin write (a[j]); c[m]:=c[m]+a[j]; end;
writeln;
end;
writeln('A teper summy cifr');
for j:=2 to 16 do
begin writeln (j,' ', c[j]); end;
ReadLn;
maximum:=c[2];
for j:=2 to 16 do
if c[j]>maximum then maximum:=c[j];
writeln('osnovaniya c mmximalnoy summoy cifr');
for j:=2 to 16 do
if c[j]=maximum then writeln(j);
readln
end.
35. «Фибоначчиева система счисления» (9-11 кл)
Фибоначчиева система счисления — смешанная система счисления для целых чисел на основе
чисел Фибоначчи F2=1, F3=2, F4=3, F5=5, F6=8 и т.д.
Последовательность Фибоначчи определяется следующим образом:
F1=F2=1
i>2:
Fi= F i-1+F i-2,
Несколько первых её членов : 1, 1, 2, 3, 5, 8, 13, 21, 34,…
В Фибоначчиевой системе счисления участвуют все элементы последовательности, кроме
первой единицы.
36
Фибоначчиева система счисления
Теорема Цекендорфа утверждает, что любое натуральное число n можно представить
единственным образом в виде суммы чисел Фибоначчи:
Запись
в ФСС
0……0
1
10
100
101
1000
1001
1010
10000
Число
где k1 >= k2+2, k2 >= k3+2, ... , kr >= 2
Отсюда следует, что любое число можно однозначно записать в
фибоначчиевой системе счисления, например:
0
F2=1
F3=2
F4=3
4
F5=5
6
7
F6=8
Перевод числа в фибоначчиеву систему счисления
осуществляется простым "жадным" алгоритмом: просто
перебираем числа Фибоначчи от больших к меньшим и, если некоторое
запись числа , и мы отнимаем
от и продолжаем поиск.
, то
входит в
Надо написать программу для перевода натурального числа N в фибоначчиеву систему
счисления.
Формат входных данных
Первая строка входного файла содержит натуральное число N (1≤N≤231-1).
Формат выходных данных
Выходной файл должен содержать строку, содержащую код Фибоначчи числа N.
Пример входного и выходного файлов
Пример входных данных
12
5
Код программы (Pascal)
program bif;
uses crt;
var
a,b,c,j,n,i:longint;
f:array [1..100] of longint;
ind:array [1..100] of integer;
Пример выходных данных
10101
1000
{massiv dlia riada fibonacchi}
{massiv dlia coda fibonacchi}
37
begin
clrscr;
write ('chislo'); readln(n);
{vyraschivaem ryad do chisla n }
f[1]:=1; f[2]:=2; i:=2;
while f[i]<=n do
begin
i:=i+1;
f[i]:=f[i-1]+f[i-2];
end;
{obnulyaem massiv coda}
for j:=1 to i do ind[j]:=0 ;
{stroim cod. Dlia etogo idem po ryady fibonacchi vniz i nahodim naibol'shii
element riada men'shii ili ravnii chislu n. V massiv index stavim edinicu,
i vichitaem iz chisla naidennyi element ryada. I tak do teh por, poka chislo ne
obnulim. CChtoby n ne portit' my rabotaem
c ego copyey a }
b:=i; a:=n;
while a>0 do
begin
while a< f[b] do b:=b-1;
ind[b]:=1;
a:=a-f[b];
end;
write ('cod Fibonacchi=');
for j:=i-1 downto 1 do
write (ind[j]);
end.
36. «Криптографические ключи» (9-11 кл)
Недавно одна компания “X” разработала принципиально новый алгоритм шифрования
данных, который практически невозможно взломать, но и одновременно абсолютно не
ресурсоемкий. Все шифрование строится на симметричном K-ключе, то есть на числе, в
двоичной записи которого ровно K единиц. Все принципиальное отличие от предыдущих
алгоритмов заключалось в том, что ключ не был одним и тем же на все время соединения, а
менялся после некоторых определенных интервалов времени на другой K-ключ. Также одной из
особенностей разработанного алгоритма была необходимость того, чтобы каждый следующее
число, соответствующее K-ключу, было больше предыдущего. Более того, специалисты
компании установили, что для увеличения помехоустойчивости разница между следующим Kключом и предыдущим K-ключом должна быть минимальна. Под разницей K-ключей
понимается абсолютная разница соответствующих им чисел.
Вы работаете в этой компании, и Вам предстоит разработать алгоритм получения из
исходного K-ключа следующего K-ключа в соответствии со всеми описанными выше
требованиями.
Формат входных данных
В первой и единственной строке входного файла находится одно натуральное число N (1
≤ N ≤ 1018) – соответствующий K-ключ.
Формат выходных данных
В первой и единственной строке выходного файла должно находится одно натуральное
число – следующий K-ключ за соответствующим K-ключом N.
38
Пример входного и выходного файлов
Пример входных данных
2
Пример выходных данных
4
22
25
1536
2049
Код программы (Pascal)
uses
crt;
var
i,v,x,m,j, maximum, sum, summa : longint;
begin
clrscr;
write('Vvodim chislo'); ReadLn(x); m:=2;
v:=x; sum:=0 ;
While v>0 do
begin
sum:=sum+v mod m;
v:=v div m
end;
summa:=sum;
writeln (x);
repeat
x:=x+1;
sum:=0;
v:=x ;
While v>0 do
begin
sum:=sum+v mod m;
v:=v div m;
end;
until summa=sum;
writeln(x);
end.
39
Решения задач городской (районной) олимпиады (2013 г.)
Приведены примеры программ или их фрагменты в программе PascalABC. Возможные
решения могут отличаться от предложенных, но они должны быть достаточно краткими.
Одна из идей решения – преобразовать
сравнить соответствующие части.
число
и
его
квадрат
в
строки
и
Пример программы:
Program kvadr;
var
a,b,lenx,leny:integer;
i,k:real;
x,y:string;
f:text;
begin
write('введите A, B'); readln(a,b);
i:=a;
while i<= b do
begin
k:=i*i;
str(i,x);
/преобразует число i в строковый формат х
lenx:=length(x);
str(k,y);
leny:=length(y);
if x=Copy(y,leny-lenx+1,lenx) then writeln(i,' ',k);
i:=i+1;
end;
end.
Задача на поиск максимальной величины без хранения последовательности.
Пример программы:
program numeric;
uses crt;
var
40
c:string;
k,max:integer;
begin
read(c);
k:=0; max:=0;
for i:=1 to length(c) do
begin
if ('0'<=copy(c,i,1)) and ((copy(c,i,1) <='9')
then begin k:=k+1;
if max<k then max:=k; end
else k:=0;
end;
if max>0 then writeln('max numeric = ' , max)
else writeln('исел в последовательности нет');
end.
Задача на реализацию предложенного алгоритма.
Программа:
program kodirovka;
const max2=20;
var
a,b:array[1..max2] of integer;
n,n1,i,j,st,k:integer;
begin
readln(n);
i:=max2;
n1:=n;
41
{перевод числа в двоичную форму}
while n1>0 do
begin
a[i]:=n1 mod 2;
n1:=n1 div 2;
i:=i-1;
end;
{изменение двоичного числа по предложенным правилам}
for j:=i+1 to max2 do
begin
if j=i+1
then b[j]:=a[j]
else if a[j]=a[j-1]
then b[j]:=1
else b[j]:=0
end;
{перевод двоичного числа в десятичное}
k:=0;
st:=1;
for j:=max2 downto i+1 do
begin
k:=k+b[j]*st;
st:=st*2;
end;
writeln(k);
end.
Искомая величина - наибольший общий делитель длин проекций отрезка на оси координат
(итоговый результат за минусом одной точки – конца отрезка).
Также возможно решение в просмотре всех целочисленных координат в диапазоне от
минимальной до максимальной на предмет принадлежности данному отрезку.
Пример программы:
program geometry;
var
x,y,x1,y1,x2,y2,ost,otvet:integer;
begin
write('введите x1,y1 ');
readln(x1,y1);
42
write('введите x2,y2 ');
readln(x2,y2);
x:=abs(x1-x2);
y:=abs(y1-y2);
while
y<>0
do
begin
ost := x mod y;
x := y;
y := ost;
end;
otvet:=x-1;
writeln('(',x1,';',y1,') (', x2,';',y2,')','kol=',otvet);
end.
Задача на динамическое программирование.
Пусть A[i-1]-количество способов разложить число i-1 на слагаемые.
Число i можно получить из i-1,i-2,…,i-k добавлением соответствующего
слагаемого.
Тогда A[i]=A[i-1]+A[i-2]+…+A[i-k]
Находим последовательно A[1]…A[n], величина A[n]-есть искомое решение.
Переборное решение подходит только для первых двух тестов.
Пример программы:
program razlogenie;
var
i,j,k,n,m:longint;
a:array[1..50] of real;
begin
43
write('input k , n');
readln(k,n);
a[1]:=1;
for i:=2 to n
do begin
if i<=k then a[i]:=1 else a[i]:=0;
m:=i-k;
if m<=0 then m:=1;
for j:=m to i-1
do a[i]:=a[i]+a[j];
end;
writeln('kolvo= ',a[n]:2:0);
end.
44
Download