Реши задачу с фото на с++

تم الإنشاء في: ٢٢ أبريل ٢٠٢٦

تمت الإجابة باستخدام GPT-5.3 بواسطة Chat01

سؤال

20260422_161306.jpg

Реши задачу с фото на с++

الفكرة

Thought for 10s

الإجابة

Вот решение на C++.

Идея простая:
для каждого числа запоминаем его первое появление.
Когда встречаем это число снова на позиции i, считаем расстояние:

i - first_pos[x]

и обновляем максимум.

Если одинаковых элементов нет, ответ будет 0.

Код

cpp
#include <iostream> #include <unordered_map> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; unordered_map<long long, int> first_pos; int ans = 0; for (int i = 1; i <= N; i++) { long long x; cin >> x; if (first_pos.find(x) == first_pos.end()) { first_pos[x] = i; // запоминаем первое вхождение } else { ans = max(ans, i - first_pos[x]); } } cout << ans; return 0; }

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

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

Сложность

  • По времени: O(N) в среднем
  • По памяти: O(K), где K — число различных элементов

Пример

Для массива: 1 2 3 1 2 2 4 5 6 7

  • для 1: позиции 1 и 4, расстояние 3
  • для 2: позиции 2, 5, 6, максимум 6 - 2 = 4

Ответ: 4

Если хочешь, могу еще дать версию через map или очень короткое решение без комментариев для сдачи.

سؤال

20260422_162225.jpg

Вот этот код у меня не проходит по памяти поч

الفكرة

Thought for a few seconds

الإجابة

Да, проблема, скорее всего, в unordered_map.

При N до 1000000 он может съесть слишком много памяти из-за:

  • хранения хеш-таблицы,
  • бакетов,
  • служебных указателей,
  • плохого overhead на каждый элемент.

У тебя по условию лимит памяти 32 МБ, и unordered_map легко в него не влезает.

Что сделать лучше

Есть два варианта.

Вариант 1. Если числа не очень большие

На фото видно фразу:

как минимум в половине тестов все числа не превышают 10000

Но это только для половины тестов, значит на всех тестах так делать нельзя:

cpp
vector<int> pos(10001);

Это не универсальное решение.


Вариант 2. Правильное решение для всех тестов — координатное сжатие

Нужно:

  1. считать все числа в массив,
  2. сделать копию и отсортировать,
  3. убрать дубликаты,
  4. каждому числу сопоставить его индекс,
  5. хранить первое вхождение уже по этому индексу в обычном vector<int>.

Так памяти уйдет намного меньше, чем у unordered_map.

Решение, которое пройдет по памяти

cpp
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<long long> a(n), b; for (int i = 0; i < n; i++) { cin >> a[i]; } b = a; sort(b.begin(), b.end()); b.erase(unique(b.begin(), b.end()), b.end()); vector<int> first(b.size(), -1); int ans = 0; for (int i = 0; i < n; i++) { int id = lower_bound(b.begin(), b.end(), a[i]) - b.begin(); if (first[id] == -1) { first[id] = i; } else { ans = max(ans, i - first[id]); } } cout << ans << '\n'; return 0; }

Почему это экономит память

У тебя теперь:

  • aN чисел,
  • bN чисел,
  • first — до N чисел.

Это в основном просто массивы, без огромного overhead, как у unordered_map.


Почему твой код может падать по памяти

Вот эта строка:

cpp
unordered_map<ll, int> mp;

создает структуру, где на 1 элемент тратится заметно больше памяти, чем на pair<int,int> в массиве.
Для миллиона разных чисел это уже очень дорого.


Еще замечание по твоему коду

У тебя:

cpp
if (mp[x] == 0) mp[x] = i; else ans = max(ans, i - mp[x]);

mp[x] через operator[] создает элемент, если его не было.
Это тоже лишняя нагрузка.

То есть даже логически лучше было бы писать так:

cpp
auto it = mp.find(x); if (it == mp.end()) mp[x] = i; else ans = max(ans, i - it->second);

Но по памяти unordered_map все равно может не пройти.


Если хочешь оставить идею с хешем

Можно попробовать чуть уменьшить расход:

cpp
mp.reserve(n); mp.max_load_factor(0.7);

Но при лимите 32 МБ это все равно рискованно.


Самый надежный вариант здесь — сжатие координат + vector.

Если хочешь, я могу еще дать совсем компактную версию этого решения в стиле олимпиадного шаблона.

مشاركة هذا السؤال والجواب