Программное решение задач ЕГЭ по информатике

Задача 5643. Источник: Поляков. Задание КИМ 24

Страница задачи 5643

(П. Финкель) Текстовый файл 24-228.txt состоит не более чем из 106 символов и содержит буквы английского алфавита и цифры. Определите максимальное число в этом файле, ограниченное двумя парами символов SS и удовлетворяющее маске «12????77??9», где символ ? обозначает любую цифру. Пример такого числа: «12123477129». Найдите сумму нечётных цифр и произведение чётных цифр найденного числа, запишите в качестве ответа сумму этих двух чисел.

Решение

У тех, кто знаком с возможностями языков Python и PascalABC возникает желание использовать метод split, но этого делать нельзя. Файл содержит последовательности из трех букв S (потенциально могут быть и более длинные последовательности с нечетным количеством символов), которые не будут корректно обработаны данным методом. Хотя в файле нет чисел после такой комбинации, нет гарантии, что таких чисел не будет в другом файле, что может привести к неверному ответу. Правильным решением является последовательный поиск комбинаций SS и анализ подстрок между ними. Искать комбинации можно через посимвольный поиск или через использование стандартных методов поиска в строке.

Python через посимвольный анализ

s = open('24-228.txt').readline()
mx = ''
last = -1
for i in range(len(s) - 1):
    if s[i] == 'S' and s[i + 1] == 'S':
        if last != - 1:
            s1 = s[last + 2:i]
            if len(s1) == 11 and s1.isdigit():
                if s1[:2] == '12' and s1[6:8] == '77' and s1[10] == '9':
                    mx = max(mx, s1)
        last = i
m = 1
sm = 0
for c in mx:
    if int(c) % 2 == 1:
        sm += int(c)
    else:
        m *= int(c)
print(sm + m)

Python через использование средств поиска в строке

s = open('24-228.txt').readline()
mx = ''
start = s.find('SS')
while (start != -1):
    finish = s.find('SS', start + 1)
    if finish != -1:
        s1 = s[start + 2: finish]
        if len(s1) == 11 and s1.isdigit():
            if s1[:2] == '12' and s1[6:8] == '77' and s1[10] == '9':
                mx = max(mx, s1)
    start = finish
m = 1
sm = 0
for c in mx:
    if int(c) % 2 == 1:
        sm += int(c)
    else:
        m *= int(c)
print(sm + m)

PascalABC через посимвольный анализ

function IsDigit(s: String): Boolean;
var
    c: Char;
begin
    result := True;
    foreach c in s do
        if not c.IsDigit() then
        begin
            result := False;
            break;
        end;
end;

var
    last, i, m, sum: Integer;
    max, s, s1: String;
    c: Char;
    f: TEXT;
begin
    Assign(f, '24-228.txt');
    Reset(f);
    Readln(f, s);
    max := '';
    last := -1;
    for i := 1 to s.Length - 1 do
        if (s[i] = 'S') and (s[i + 1] = 'S') then
        begin
            if last <> -1 then
            begin
                s1 := s[last + 2:i];
                if (s1.Length = 11) and IsDigit(s1) then
                    if (s1[:3] = '12') and (s1[7:9] = '77') and (s1[11] = '9') then
                        if s1 > max then
                            max := s1;
            end;
            last := i;
        end;
    m := 1;
    sum := 0;
    foreach c in max do
        if ord(c) mod 2 = 1 then
            sum := sum + ord(c) - 48
        else
            m := m * (ord(c) - 48);
    Writeln(sum + m);
end.

PascalABC через использование средств поиска в строке

function IsDigit(s: String): Boolean;
var
    c: Char;
begin
    result := True;
    foreach c in s do
      if not c.IsDigit() then
      begin
            result := False;
            break;
      end;
end;

var
    start, finish, m, sum: Integer;
    max, s, s1: String;
    c: Char;
    f: TEXT;
begin
    Assign(f, '24-228.txt');
    Reset(f);
    Readln(f, s);
    max := '';
    start := s.IndexOf('SS');
    while start <> -1 do
    begin
        finish := s.IndexOf('SS', start + 1);
        if finish <> -1 then
        begin
            s1 := s[start + 3:finish + 1];
            if (s1.Length = 11) and IsDigit(s1) then
                if (s1[:3] = '12') and (s1[7:9] = '77') and (s1[11] = '9') then
                    if s1 > max then
                        max := s1;
        end;
        start := finish;
    end;
    m := 1;
    sum := 0;
    foreach c in max do
        if ord(c) mod 2 = 1 then
            sum := sum + ord(c) - 48
        else
            m := m * (ord(c) - 48);
    Writeln(sum + m);
end.

C++ через посимвольный анализ

#include <iostream>
#include <fstream>
using namespace std;

bool isdigit(string s)
{
    for (int i = 0; i < s.length(); i++)
        if (s[i] < '0' or s[i] > '9')
            return false;
    return true;
}

int main()
{
    ifstream f;
    f.open("24-228.txt");
    string s, max = "";
    f >> s;
    int last = -1;
    for (int i = 0; i < s.length() - 1; i++)
        if (s[i]== 'S' && s[i + 1] == 'S')
        {
            if (last != -1)
            {
                string s1 = s.substr(last + 2, i - last - 2);
                if (s1.length() == 11 and isdigit(s1))
                    if (s1.substr(0, 2) == "12" && s1.substr(6, 2) == "77" && s1[10] == '9')
                        if (s1 > max)
                            max = s1;
            }
            last = i;
        }
    int m = 1, sum = 0;
    for (int i = 0; i < max.length(); i++)
        if ((int)max[i] % 2 == 1)
            sum += (int)max[i] - 48;
        else
            m *= (int)max[i] - 48;
    cout << sum + m << endl;
}

C++ через использование средств поиска в строке

#include <iostream>
#include <fstream>
using namespace std;

bool isdigit(string s)
{
    for (int i = 0; i < s.length(); i++)
        if (s[i] < '0' or s[i] > '9')
            return false;
    return true;
}

int main()
{
    ifstream f;
    f.open("24-228.txt");
    string s, max = "";
    f >> s;
    int start = s.find("SS");
    while (start != -1)
    {
        int finish = s.find("SS", start + 1);
        if (finish != -1)
        {
            string s1 = s.substr(start + 2, finish - start - 2);
            if (s1.length() == 11 and isdigit(s1))
                if (s1.substr(0, 2) == "12" && s1.substr(6, 2) == "77" && s1[10] == '9')
                    if (s1 > max)
                        max = s1;
        }
        start = finish;
    }
    int m = 1, sum = 0;
    for (int i = 0; i < max.length(); i++)
        if ((int)max[i] % 2 == 1)
            sum += (int)max[i] - 48;
        else
            m *= (int)max[i] - 48;
    cout << sum + m << endl;
}

Ответ

49183

Отправить замечание по решению

Код по которому имеется замечание:

Ваш вариант кода:

Комментарий: