Продолжаем разбирать олимпиадные задачи на программирование школьного тура Всероссийской олимпиады школьников по информатике. Первые две задачи были разобраны в прошлой статье (можете перейти по ссылкам ниже).
Список задач:
- Шахматная доска
- Манхеттен
- Пятница, 13-е
- Автомобильные номера
- Числа-палиндромы
Полный текст заданий можете посмотреть по ссылкам:
ВОШ по информатике школьный этап 9-11 классы (2014 г.)
ВОШ по информатике школьный этап 7-8 классы (2014 г.)
Задача №3. Пятница, 13-е.
Календарь жителей планеты Плюк состоит из N месяцев, каждый месяц состоит ровно из 30 дней, неделя состоит из 7 дней. Особо несчастливыми на планете Плюк
считается 13-е число месяца, если оно выпадает на пятницу. Известно, что Новый год на планете Плюк начался в k-й по счету день недели (1-й день недели — понедельник, 2-й — вторник, 3-й — среда, … , 7-й — воскресенье).
Определите, сколько в этом году на планете Плюк будет особо несчастливых пятниц, 13-е. Программа получает на вход два натуральных числа, записанных в отдельных
строках. Первое число — количество месяцев в календаре планеты Плюк N, не превосходящее 109. Второе число — номер дня недели, на который приходится первое число
первого месяца нового года, может принимать значения от 1 до 7.
Программа должна вывести единственное натуральное число — количество несчастливых дней в этом году.
Решение
Рассмотрим несколько месяцев в году на планете Плюк:
Как видите:
- пятница может стоять 13-м числом, если первый день месяца — воскресенье (7-ой день недели);
- каждый последующий месяц первый день месяца сдвигается на два дня (был — понедельник, стал — среда; и т.д.)
В цикле (который перебирает все месяцы в году на планете) создадим условие, проверяющее: является ли 13-е число пятым по счету днем недели (т.е. пятницей).
Я использовал для решения следующее условие:
if (m+12) mod 7 =5 then k:=k+1;
оно будет истинно только в случае, когда m — седьмой день недели (19 mod 7 = 5); k — счетчик пятниц 13-ых. m — понедельник (m=1), m — вторник (m=2) и т.д.
var n,m,i,k:longint; begin readln(n,m); for i:=1 to n do begin if (m+12) mod 7 =5 then k:=k+1; m:=m+2; // т.к. 1-е число каждого последующего месяца сдвигается на 2 if m=8 then m:=1; if m=9 then m:=2; end; writeln(k); end.
Рассмотрим последние два условия:
if m=8 then m:=1; if m=9 then m:=2;
Если в настоящий месяц первой число — это суббота или воскресенье, то после выполнения команды m:=m+2 значение m может быть равным 8 или 9. Но нам нужна первая неделя месяца, чтобы проверить условие
if (m+12) mod 7 =5 then k:=k+1;
поэтому мы переопределяем переменную m
Задача №4. Автомобильные номера
В Российской Федерации на разных видах транспортных средств устанавливаются разные по формату регистрационные знаки («автомобильные номера»). Вот пример
нескольких возможных форматов регистрационных знаков.
В этой задаче «буквой» может быть любая заглавная буква латинского алфавита. Напишите программу, которые по регистрационному знаку определяет его тип или
определяет, что регистрационный знак некорректен. Программа получает на вход три строки текста, каждая строка содержит один образец регистрационного знака (возможно, некорректный). Каждый образец содержит от 1 до 10 символов, являющихся цифрами и заглавными латинскими буквами (других символов во входных данных быть не может).
Программа должна вывести для каждого образца число, соответствующее типу транспортного средства, как в приведенной таблице, то есть 1 — для частных транспортных
средств, 2 — для общественного транспорта, 3 — для прицепов, 4 — для мотоциклов. Если номерной знак некорректен (не подходит ни к одному из указанных типов), то необходимо вывести число 0. Каждое число необходимо выводить в отдельной строке.
Решение
Привожу пример моего решения с комментариями. Если Вы решили задачу проще — пишите в комментариях.
var num : array[0..9] of integer; //массив ascii кодов цифр от 0 до 9 blet : array[0..30] of integer; //массив ascii кодов заглавных букв от A до Z ress: array[1..3] of integer; let: string; a,res:string; i,j,k,length_a,result,q,w,code:integer; begin for q:=1 to 3 do begin // 3 раза вводим набор символов readln(a); RES:=''; //обнуляем значение строковой переменной // формируем массивы ascii кодов for i:=0 to 9 do num[i]:=i+48; // заглавный букв for j:=0 to 25 do blet[j]:=j+65; // строк // считаем длину символов в строках length_a:=length(a); if (length_a>6) or (length_a<5) then begin res[q]:='0'; end else begin // если количество символов не удовлетворяет условию, то для q-го слова значение res[q]='0' for w:=0 to length_a-1 do begin let:= copy(a,length_a-w,1); // перебираем в цикле каждый символ введенной цепочки, начиная с последнего for i:=1 to 9 do begin if let=chr(num[i]) then begin res:=res+'1' ;break; end; // сравниваем этот символ с элементами массива цифр. Если условие выполняется, то приписываем к строковой переменной res единичку end; for j:=0 to 25 do begin if let=chr(blet[j]) then begin res:=res+'2' ;break; end; // сравниваем этот символ с элементами массива заглавных букв. Если условие выполняется, то приписываем к строковой переменной res единичку end; end; end; Val(res,ress[q],code); // набор единичек и двоек в переменной res преобразуем в число (тип integer) end; for q:=1 to 3 do begin // сравниваем полученный набор 1 и 2 (цифр и букв) с шаблонами, заданными в условии задачи CASE ress[q] of 221112: writeln('1'); 11122: writeln('2'); 111122: writeln('3'); 221111: writeln('4'); ELSE WRITELN('0'); end; end; end.
Задача №5. Числа-палиндромы.
Палиндромом называется строка, которая одинаково читается как слева направо, так и справа налево. Рассмотрим все натуральные числа, запись которых в десятичной системе счисления является палиндромом (при этом запись не начинается с нуля). Например, числа 121 и 1331 являются палиндромами, а число 123 — нет. По данному числу N найдите N-e в порядке возрастания число-палиндром.
Программа получает на вход одно натуральное число N, не превосходящее 100 000. Программа должна вывести одно натуральное число — N-е в порядке возрастания
число-палиндром.
Решение