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

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

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

(В. Шубинкин) Текстовый файл 24-268.txt состоит не более чем из 106 символов и содержит только заглавные буквы латинского алфавита и цифры. В файле записаны числа в тридцатеричной системе счисления, окружённые символами, не являющимися цифрами в этой системе счисления или началом/концом файла. Лидирующие нули в записи чисел не допускаются. Определите самую длинную последовательность в этом файле, которая может представлять собой запись числа в тридцатеричной системе счисления, где чётные и нечётные цифры чередуются. Если таких последовательностей несколько, выберите ту, числовое значение которой наименьшее. Например, в последовательности Z12345UABCX11111XX0123456Y98765 есть три тридцатеричных числа с чередующейся чётностью цифр: 12345, ABC, 98765. Наибольшая длина – 5. Наименьшее числовое значение последовательности с такой длиной – 12345.

Алфавит тридцатеричной системы счисления: 0123456789ABCDEFGHIJKLMNOPQRST.

Решение

Более коротким будет решение с использованием метода разделения строк. Заменяем все буквы, не входящие в тридцатеричную систему счисления на какую-то одну и делим строку на подстроки по этой букве. Каждую подстроку анализируем на условие задачи и находим ответ. Анализ строки лучше вынести в отдельную функцию, возвращающую логическое значение.

Python с разделением строки методом split

def good(s):
    if len(s) == 0 or s[0] == '0':
        return False
    d = '0123456789'
    for i in range(len(s) - 1):
        if ((s[i] in d) == (s[i + 1] in d) and ord(s[i]) % 2 == ord(s[i + 1]) % 2 or
            (s[i] in d) != (s[i + 1] in d) and ord(s[i]) % 2 != ord(s[i + 1]) % 2):
            return False
    return True


s = open('24-268.txt').readline()
for i in 'UVWXY':
    s = s.replace(i, 'Z')
mx = ''
for i in s.split('Z'):
    if good(i) and (len(i) > len(mx) or len(i) == len(mx) and i < mx):
        mx = i
print(mx)

PascalABC с разделением строки методом split

function good(s: String): Boolean;
var
    i: Integer;
    d: Set of Char;
begin
    result := True;
    if (s.Length = 0) or (s[1] = '0') then
        result := False
    else
        d := ['0'..'9'];
        for i := 1 to s.Length - 1 do
            if (((s[i] in d) = (s[i + 1] in d)) and (ord(s[i]) mod 2 = ord(s[i + 1]) mod 2) or
            ((s[i] in d) <> (s[i + 1] in d)) and (ord(s[i]) mod 2 <> ord(s[i + 1]) mod 2)) then
            begin
                result := False;
                break;
            end;
end;

var
    i: Integer;
    s, mx: String;
    ss: Array of String;
    c: Char;
    f: TEXT;
begin
    Assign(f, '24-268.txt');
    Reset(f);
    Readln(f, s);
    for c := 'U' to 'Y' do
        s := s.Replace(c, 'Z');
    ss := s.Split('Z');
    for i := 0 to ss.Length - 1 do
        if good(ss[i]) and ((ss[i].Length > mx.Length) or
                            (ss[i].Length = mx.Length) and (ss[i] < mx)) then
            mx := ss[i];
    Writeln(mx);
end.

Альтернативным вариантом решения является классический посимвольный анализ. Накапливаем в переменной r строку от одного символа, не входящего в тридцатеричную систему счисления, до другого. Параллельно анализируем, чередуются ли четные и нечетные цифры, отражая это в значении переменной good. Для этого сохраняем предыдущий символ в переменной last. Если оба соседних символа являются цифрами или оба являются буквами, то четность их кодов должна быть различной, а, если один символ является цифрой, а другой - буквой, то их четность должна совпадать. Достигнув разделительного символа, проверяем накопленную строку на соответствие условию задачи и сбрасываем переменные в исходное состояние для поиска следующей строки. Обязательно после цикла следует сделать анализ накопленной строки, т.к. решением может быть последняя подстрока, ограниченная концом файла.

Python с посимвольным анализом

s = open('24-268.txt').readline()
r = ''
mxr = ''
d = '0123456789'
last = ''
good =True
for i in s:
    if i > 'T':
        if (good and len(r) > 0 and r[0] != '0' and
            (len(r) > len(mxr) or len(r) == len(mxr) and r < mxr)):
            mxr = r
        r = ''
        last = ''
        good = True
    else:
        if (last == '' or (i in d) == (last in d) and ord(i) % 2 != ord(last) % 2 or
            (i in d) != (last in d) and ord(i) % 2 == ord(last) % 2):
            r += i
            last = i
        else:
            good = False
if (good and len(r) > 0 and r[0] != '0' and
    (len(r) > len(mxr) or len(r) == len(mxr) and r < mxr)):
    mxr = r
print(mxr)

PascalABC с посимвольным анализом

var
    i: Integer;
    s, r, mxr: String;
    last: Char;
    good: Boolean;
    d: Set of Char;
    f: TEXT;
begin
    Assign(f, '24-268.txt');
    Reset(f);
    Readln(f, s);
    r := '';
    mxr := '';
    d := ['0'..'9'];
    last := ' ';
    good := True;
    for i := 1 to s.Length do
        if s[i] > 'T' then
        begin
            if good and (r.Length > 0) and (r[1] <> '0') and
               ((r.Length > mxr.Length) or (r.Length = mxr.Length) and (r < mxr)) then
                mxr := r;
            r := '';
            last := ' ';
            good := True;
        end
        else
        begin
            if (last = ' ') or
               ((s[i] in d) = (last in d)) and (ord(s[i]) mod 2 <> ord(last) mod 2) or
               ((s[i] in d) <> (last in d)) and (ord(s[i]) mod 2 = ord(last) mod 2) then
                begin
                    r := r + s[i];
                    last := s[i];
                end
                else
                    good := False;
        end;
    if good and (r.Length > 0) and (r[1] <> '0') and
       ((r.Length > mxr.Length) or (r.Length = mxr.Length) and (r < mxr)) then
        mxr := r;
    Writeln(mxr);
end.

C++ с посимвольным анализом

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    ifstream f;
    f.open("24-268.txt");
    string s, r = "", mxr = "", d = "0123456789";
    char last = ' ';
    bool good = true;
    f >> s;
    for (int i = 0; i < s.length(); i++)
        if (s[i] > 'T')
        {
            if (good && r.length() > 0 && r[0] != '0' &&
                (r.length() > mxr.length() || r.length() == mxr.length() && r < mxr))
                mxr = r;
            r = "";
            last = ' ';
            good = true;
        }
        else
        {
            if (last == ' ' ||
                d.find(s[i]) == d.find(last) && (int)s[i] % 2 != (int)last % 2 ||
                d.find(s[i]) != d.find(last) && (int)s[i] % 2 == (int)last % 2)
            {
                r += s[i];
                last = s[i];
            }
            else
                good = false;
        }
    if (good && r.length() > 0 && r[0] != '0' &&
        (r.length() > mxr.length() || r.length() == mxr.length() && r < mxr))
        mxr = r;
    cout << mxr << endl;
}

Ответ

8NERO9KLST

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

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

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

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