- Баллы
- 96
- Имя в Minecraft
- i0xHeX
Всем привет!
Пока подтягиваю знания по C++ для решения целевой задачи, о которой писал ранее, решил добить старую добрую олимпиадную задачу, которую еще встречал в школьные времена во время подготовок. По Java у них беда (JIT не работает, 90мс минимум). На вид простая, на алгоритм - простая. На прохождение тестов - адовая.
Сама задача:
https://www.e-olymp.com/ru/problems/21
Классика, жадный алгоритм. Насколько я понял, за каждую "итерацию" нам нужно мержить 2 минимальные суммы, чтобы за N-1 итераций забрать как можно меньше денег у фирмы. Чтобы не парится на первое время с массивами и смещением элементов, используем multiset<>, идеально подходит для хранения возможных повторяющихся значений в RB-дереве. Получился примерно такой код (*):
И вот незадача - по тестам проходит только 50% положительно, 1 тест выходит за время (ну да ладно, это на десерт), остальные неправильный ответ. (Для отправки решений нужна регистрация)
Вот здесь загвоздка. Ничего не известно о выходной точности, но не помогает ни округление до 2 (еще меньше заходит), ни увеличение точности (long double - те же 50%). И все же как то ребята порешали некоторые...
Вдруг есть идеи? Какие еще подводные камни могут быть?
Пока подтягиваю знания по C++ для решения целевой задачи, о которой писал ранее, решил добить старую добрую олимпиадную задачу, которую еще встречал в школьные времена во время подготовок. По Java у них беда (JIT не работает, 90мс минимум). На вид простая, на алгоритм - простая. На прохождение тестов - адовая.
Сама задача:
https://www.e-olymp.com/ru/problems/21
Классика, жадный алгоритм. Насколько я понял, за каждую "итерацию" нам нужно мержить 2 минимальные суммы, чтобы за N-1 итераций забрать как можно меньше денег у фирмы. Чтобы не парится на первое время с массивами и смещением элементов, используем multiset<>, идеально подходит для хранения возможных повторяющихся значений в RB-дереве. Получился примерно такой код (*):
PHP:
#include <iostream>
#include <iterator>
#include <set>
using namespace std;
int main() {
// read data
int amount;
double percent;
multiset<double> cash;
cin >> amount >> percent;
percent = 1 - (percent / 100.0);
double input;
for (int i = 0; i < amount; ++i) {
cin >> input;
cash.insert(input);
}
// remove first & second lowest elements
// apply new value and insert
while (amount-- > 1) {
auto it_orig = cash.begin(), it = it_orig;
double summ = percent * ((* it++) + (* it++));
cash.erase(it_orig, it);
cash.insert(summ);
}
cout << * cash.begin();
return 0;
}
И вот незадача - по тестам проходит только 50% положительно, 1 тест выходит за время (ну да ладно, это на десерт), остальные неправильный ответ. (Для отправки решений нужна регистрация)
Вот здесь загвоздка. Ничего не известно о выходной точности, но не помогает ни округление до 2 (еще меньше заходит), ни увеличение точности (long double - те же 50%). И все же как то ребята порешали некоторые...
Вдруг есть идеи? Какие еще подводные камни могут быть?
Последнее редактирование:
