Задача 5804. Источник: Поляков. Задание КИМ 17
(П. Финкель) В файле 17-346.txt содержится последовательность целых чисел. Элементы последовательности могут принимать целые значения от 1 до 200 000 включительно. Определите количество троек последовательности, для которых произведение всех чётных цифр трёх чисел не превосходит 2·109 и удовлетворяет маске «11*6*». В качестве ответа укажите количество таких троек и наибольшее произведение их цифр. В данной задаче под тройкой подразумевается три идущих подряд элемента последовательности.
Решение
Обрабатывать тройки чисел лучше всего в виде списка (массива), что позволяет уменьшить объем кода за счет использования цикла. Решение с анализом соответствия произведения шаблону через флаговую переменную. В заданиях 5803, 5801 и 5799 представлен альтернативный анализ через операции со строками.
Python
f = open("17-346.txt")
d = [int(i) for i in f]
k = 0
mx = 0
for i in range(len(d) - 2):
p = 1
for j in range(3):
z = d[i + j]
while z > 0:
if z % 2 == 0:
p *= z % 10
z //= 10
if p <= 2000000000:
flag = False
z = p
while z > 99:
flag = flag or z % 10 == 6
z //= 10
flag = flag and z == 11
if flag:
k += 1
mx = max(mx, p)
print(k, mx)
PascalABC
var
k, max, z, i: Integer;
p: int64;
d: array [1..3] of Integer;
flag: Boolean;
f: TEXT;
begin
Assign(f, '17-346.txt');
Reset(f);
k := 0;
max := 0;
Readln(f, d[1], d[2]);
while not eof(f) do
begin
Readln(f, d[3]);
p := 1;
for i := 1 to 3 do
begin
z := d[i];
while z > 0 do
begin
if z mod 2 = 0 then
p := p * (z mod 10);
z := z div 10;
end;
end;
if p <= 2000000000 then
begin
flag := False;
z := p;
while z > 99 do
begin
flag := flag or (z mod 10 = 6);
z := z div 10;
end;
flag := flag and (z = 11);
if flag then
begin
k := k + 1;
if p > max then
max := p;
end;
end;
d[1] := d[2];
d[2] := d[3];
end;
Writeln(k, ' ', max);
end.
C++
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream f;
f.open("17-346.txt");
int d[3];
int k = 0, max = 0;
f >> d[0] >> d[1];
while (f >> d[2])
{
long long p = 1;
for (int i = 0; i < 3; i++)
{
int z = d[i];
while (z > 0)
{
if (z % 2 == 0)
p *= z % 10;
z /= 10;
}
}
if (p <= 2000000000)
{
bool flag = false;
int z = p;
while (z > 99)
{
flag = flag || z % 10 == 6;
z /= 10;
}
flag = flag && z == 11;
if (flag)
{
k++;
if (p > max)
max = p;
}
}
d[0] = d[1];
d[1] = d[2];
}
cout << k << " " << max << endl;
}
Ответ
37 113246208