(Е. Джобс) На ленте исполнителя МТ в соседних ячейках записана последовательность из \(1000\) символов, включающая только нули, единицы и двойки. Ячейки справа и слева от последовательности заполнены пустыми символами «\(\lambda\)». В начальный момент времени головка расположена в ближайшей ячейке слева от последовательности.
Программа работы исполнителя:
| \(\lambda\) | \(0\) | \(1\) | |
| \(q_0\) | \(\lambda , \, R, \, q_1\) | ||
| \(q_1\) | \(\lambda , \, S, \, q_1\) | \(1, \, R, \, q_2\) | \(0, \, R, \, q_2\) |
| \(q_2\) | \(\lambda , \, S, \, q_2\) | \(0, \, S, \, q_2\) | \(1, \, R, \, q_1\) |
Команды движения каретки: \(L\) – влево, \(R\) – вправо, \(S\) – стоп. После выполнения программы на ленте осталось \(200\) нулей. Определите минимально возможное количество единиц, которое могло быть в исходной последовательности.
Решение:
Переформулируем вопрос задачи: определите максимально возможное количество нулей в исходной последовательности. Пусть на нулевой позиции находится пустой символ \(\lambda ,\) а на последующих \(1000\) позициях находятся нули и единицы. Во-первых заметим, что если в последовательности встретились два подряд идущих нуля, то исполнитель закончит свою работу обязательно либо на первом из этих нулей (если он уже находится в состоянии \(q_2,)\) либо на втором нуле. Так как мы хотим разместить как можно больше нулей в исходной строке, то часть из них должна превратиться в единицы и после работы алгоритма должно остаться \(200\) нулей. Исполнитель при переходе с нулевой (пустой) позиции в первую получает состояние \(q_1.\) Значит на первой позиции не может находится единица (иначе количество нулей увеличится, а нам нужно наоборот уменьшение нулей, раз мы хотим разместить как можно больше этих самых нулей). Значит, начало исходной строки должно представлять собой последовательность пар чисел \(01.\) После работы алгоритма такие пары переходят в две единицы: \(11.\) Мы можем разместить не больше \(400\) таких пар, раз нам нужно получить в конце \(200\) нулей. На самом деле таких пар будет ровно \(399.\) Они дадут в итоге \(798\) единиц. В запасе осталось \(202\) позиции. Помещаем на \(799\) и \(800\) позиции нули. Исполнитель на \(799\) шаге заменит \(0\) на \(1\) и перейдёт в состояние \(q_2.\) На \(800\) шаге он остановится. Так как должно остаться ровно \(200\) нулей, то на одной позиции из диапазона \([801:1000]\) размещаем одну единицу. Т.о., нам удалось разместить максимум \(600\) нулей так, чтобы в конечной строчке осталось \(200\) нулей. Значит, минимум единиц в строке будет \(1000 - 600 = 400.\)
Тест в программе
Python
mt = {'l': {'q0': 'l,R,q1', 'q1': 'l,S,q1', 'q2': 'l,S,q2'},
'0': {'q1': '1,R,q2', 'q2': '0,S,q2'},
'1': {'q1': '0,R,q2', 'q2': '1,R,q1'}}
s = ['l'] + list('01' * 399) + ['0'] * 201 + ['1'] + ['l']
p = 0
step = {'L': -1, 'R': 1, 'S': 0}
print(f'Количество единиц в начальной строке: {s.count("1")}')
state = 'q0'
act = mt[s[p]][state].split(',')
s[p] = act[0]
state = act[2]
while act[1] != 'S':
p += step[act[1]]
act = mt[s[p]][state].split(',')
s[p] = act[0]
state = act[2]
print(f'Количество нулей в конечной строке: {s.count("0")}')
Ответ: \(400\)
Эффективно готовьтесь к ЕГЭ по информатике с новым тренажёром, эмулирующем работу станции КЕГЭ, которая используется на реальном экзамене