Редакция для Маркеры в потоке


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

1. Идея

Нужно найти все позиции, где в строке потока встречается заданный символ-маркер.

Самый прямой способ: пройти по всей строке слева направо и проверить каждый символ. Если текущий символ совпадает с маркером, запоминаем его индекс.

Если после прохода совпадений не оказалось, выводим -1.

2. Наблюдения

  • Маркер состоит ровно из одного символа.
  • Индексация начинается с 0, значит первый символ строки имеет индекс 0, второй — 1 и так далее.
  • Нужно вывести все подходящие позиции в порядке возрастания. Если идти по строке слева направо, позиции автоматически будут найдены в нужном порядке.
  • Длина строки может быть до 200000, поэтому решение должно работать за линейное время. Полный один проход по строке как раз подходит.

3. Алгоритм

  1. Считать маркер и строку потока.
  2. Взять символ маркера.
  3. Создать список ответов.
  4. Для каждого индекса i от 0 до len(s) - 1:
    • если s[i] равен маркеру, добавить i в ответ.
  5. Если список ответов пуст:
    • вывести -1.
  6. Иначе:
    • вывести все найденные индексы через пробел.

4. Почему это работает

Алгоритм проверяет каждый символ строки ровно один раз.

  • Если на позиции i стоит нужный маркер, то индекс i добавляется в ответ.
  • Если на позиции i стоит другой символ, то эта позиция не должна быть в ответе, и алгоритм её не добавляет.

Значит, в итоговый список попадут все и только те индексы, где маркер действительно встречается.

Так как просмотр идёт слева направо, индексы добавляются в возрастающем порядке, как и требуется в условии.

5. Сложность

  • Время: O(n), где n — длина строки потока.
  • Память: O(k), где k — количество вхождений маркера, так как нужно сохранить найденные позиции.

6. Код на C++17

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main() {
    string marker, s;
    cin >> marker >> s;

    char ch = marker[0];
    vector<int> positions;

    for (int i = 0; i < (int)s.size(); i++) {
        if (s[i] == ch) {
            positions.push_back(i);
        }
    }

    if (positions.empty()) {
        cout << -1;
    } else {
        for (int i = 0; i < (int)positions.size(); i++) {
            if (i > 0) {
                cout << ' ';
            }
            cout << positions[i];
        }
    }

    return 0;
}

7. Код на Python 3

marker = input()
s = input()

ans = []
for i in range(len(s)):
    if s[i] == marker:
        ans.append(str(i))

if ans:
    print(" ".join(ans))
else:
    print(-1)

Комментарии

Еще нет ни одного комментария.