4-й этап Республиканской олимпиады по информатике 2021-2022, 2 тура


Задача B. MEXI

Ограничение по времени:
1.5 секунд
Ограничение по памяти:
512 мегабайт

Аза решал следующию задачу от Нархана: Вам задан массив $a$, состоящий из $n$ целых неотрицательных чисел. Назовем разделение массива $a$ на $k$ отрезков $(l_1, r_1), \ldots, (l_k, r_k)$ $x$- хорошим, если выполняются следующие условия: В этой задаче $MEX$ некоторого массива — это минимальное неотрицательное целое число, которое не содержится в этом массиве. Например: Размером $x$ хорошего разделение является количество отрезков на которое оно было разделено — то есть $k$. Вам нужно для каждого целого числа $x$ от $0$ до $n-1$ вывести минимальный возможный размер $x$ хорошего разделения, если данное разделение невыполнимо выведите $-1$.
Формат входного файла
Первая строка содержит одно целое число — $n$ ($1 <= n <= 10^6$). Вторая строка содержит $n$ целых чисел $a_1, a_2, \ldots, a_n$ $(0 <= a_i <= 10^6)$ — массив $a$.
Формат выходного файла
Выведите $n$ целых чисел, где $i$-е число — это минимальный возможный размер $x$ хорошего разделения при $x = i-1$, если данное разделение невыполнимо выведите $-1$.
Примеры:
Вход
4
0 1 0 2
Ответ
-1 3 2 1
Вход
1
2
Ответ
1
Замечание
В первом примере: ( Dimash Tursynbai )
посмотреть в олимпиаде

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

  0
2023-03-04 01:09:13.0 #

Алгоритм:

Создаем множество set_nums, в котором будем хранить все уникальные элементы массива a.

Находим минимальный элемент min_a в массиве a.

Если min_a равен 0, то выводим 1, так как разделение на отрезки единственное и состоит из всех элементов массива.

Иначе, если 0 не содержится в set_nums, то выводим 0, так как невозможно построить хорошее разделение.

Иначе, создаем переменную cur, равную минимальному элементу min_a, и удаляем его из множества set_nums.

Запускаем цикл от 1 до n+1:

Если cur содержится в set_nums, то удаляем его из множества и увеличиваем cur на 1.

Иначе, выводим текущее значение цикла и завершаем программу.

Блок-схема:

+-------------------------+

| Создать множество set |

| для уникальных элементов|

| массива a |

+-------------------------+

|

|

|

v

+----------------+

| Найти min_a в a |

+----------------+

|

|

|

v

+-------------------+

| Если min_a = 0, |

| вывести 1 и выйти|

+-------------------+

|

|

|

v

+---------------+

| Если 0 нет в |

| set_nums, |

| вывести 0 и |

| выйти |

+---------------+

|

|

|

v

+-------------------+

| Создать cur = min_a|

| и удалить его из |

| set_nums |

+-------------------+

|

|

|

v

+---------------+

| Для i от 1 до n+1|

+---------------+

|

|

|

v

+--------------------------+

| Если cur в set_nums, |

| удалить его и увеличить |

| cur на 1 |

+--------------------------+

|

|

+-----------+-------+

| | |

| v |

| Если cur не в |

| set_nums, вывести i |

| и завершить программу|

| |

v v

  0
2023-03-04 01:11:02.0 #

Алгоритм решения:

Создаем массив a[1000001] и инициализируем его нулями.

Считываем массив чисел входного файла и для каждого числа i, устанавливаем a[i] равным единице.

Выполняем проход по a, начиная с 0, и считаем количество пройденных нулей (count) и единиц (ones).

Если count + ones = n, где n - размер массива, то выводим 1, иначе выводим 2.

Пояснения:

a[i] будет равно 1, если число i содержится в массиве nums.

count - количество нулей, которые мы прошли в массиве a.

ones - количество единиц, которые мы прошли в массиве a.

Если мы прошли все элементы массива a и count + ones не равно n, то это означает, что есть число, которое не содержится в массиве. Поэтому для любого числа i от 0 до n мы можем создать разделение, в котором i не встречается, и количество отрезков в этом разделении будет равно i + 1.

Временная сложность алгоритма: O(n).

Блок-схема алгоритма:

+--------+

| Старт |

+--------+

|

v

+-----------------+

| Инициализация |

+-----------------+

|

v

+-----------------+

| Считать массив |

+-----------------+

|

v

+-----------------+

| Обработка |

+-----------------+

|

v

+-----------------+

| Вывод |

+-----------------+

|

v

+--------+

| Финиш |

+--------+

Код на языке C++:

#include <iostream>

#include <vector>

using namespace std;

int main() {

int n;

cin >> n;

vector<int> nums(n);

for (int i = 0; i < n; i++) {

cin >> nums[i];

}

vector<int> a(1000001, 0);

for (int i = 0; i < n; i++) {

a[nums[i]] = 1;

}

int count = 0, ones = 0;

for (int i = 0; i <= n; i++) {

if (a[i] == 0) {

count++;

} else {

ones++;

}

if (count + ones == n) {

cout << "1\n";

return 0;

}

}

for (int i = 0; i < n; i++) {

if (nums[i] >= n) {

cout << "2\n";

return 0;

}

}

for (int i = 0; i < n; i++) {

if (a[i] == 0) {

cout << i + 1 << "\n";

return 0;

}

}

return 0;

}

  0
2023-03-07 03:47:14.0 #

Что за позер, сейчас бы ChatGPT использовать ради того, чтоб дать свой коммент? Удали, или если у тебя есть весомая цель чтоб публиковать это, оборачивай в читаемый и спойлер код.

  0
2023-11-09 13:41:45.0 #

решение на python

показать/скрыть код