| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Алгоритмы > Задача на бинарный поиск |
| Автор: Dmi3ev 8.10.2013, 19:11 | ||
| создал тему, похоже не там вот собственно задача и реализация на с++ http://informatics.mccme.ru/moodle/mod/statements/view3.php?chapterid=2969&run_id=1710r1537#1 вот моя реализация
проходит 17/18 тестов, есть недоработки... в основном не выходит за пределы 0,012 с, а в 18-ом тесте от 2,04 до 2,08 с |
| Автор: ФедосеевПавел 9.10.2013, 16:46 |
| Может быть 18-й тест проходит на больших числах, когда hpall имеет порядок 10^18. И при конвертации в double происходит потеря точности. Попробуй реализоать всё в целочисленной арифметике. ------------------- Сейчас изменил две строки в твоём варианте - заменил ceil на целочисленное деление и инкремент - и для hd=987654321; dd=500; hp=12345678; dp=3; время работы изменилось с 2,6 с на 1,4 с. |
| Автор: Dmi3ev 9.10.2013, 19:24 |
| как именно изменил? может быть это меняет правильность решения... |
| Автор: ФедосеевПавел 9.10.2013, 21:45 | ||
Я плохо говорить на C++, но таки по смыслу
|
| Автор: Dmi3ev 9.10.2013, 23:52 | ||
так не проходит еще один тест((( |
| Автор: Mirkes 10.10.2013, 00:39 | ||
| Я не уверен, но по моему от действительной арифметики легко избавиться считая не число выживших копейщиков, а число убитых если мы поделим суммарный урон, нанесенный драконом на запас жизни одного копейщика, то целочисленное деление даст точно нужный результат! Я никогда не писал на С но думаю, что правильно исправил программу
|
| Автор: Dmi3ev 10.10.2013, 16:09 | ||
послушал вас всех и оптимизировал:
теперь все тесты летают за 0,003 с, а тот все еще не проходит... есть идеи??? |
| Автор: Dmi3ev 10.10.2013, 18:00 | ||
Так задача не решается!!! Данная замена неправильная... |
| Автор: ФедосеевПавел 10.10.2013, 19:16 | ||
| А может и правильная. Теперь мне кажется другое. 1) Тип long long целочисленный со знаком - не происходит ли переполнение разрядной сетки с изменением знака. Может попробовать unsigned long. 2) Кроме того, у Mirkes в коде присутствует маленькая ошибка - нет инициализации dpall, что приводит к неверным результатам 3) твой последний вариант не находит решения для hd=987654321; dd=500; hp=12345678; dp=3; - зависает. Предлагаю улучшить вариант Mirkes
|
| Автор: Dmi3ev 10.10.2013, 21:45 | ||
| все, решил, ура))) надо три цикла просто а не два... все ок, спасибо за помощь... посмотрел чуть с другой стороны на нее...
неправильная, я же на тестах проверяю... им можно верить... PS теперь даже при самых худших раскладах задача решается за 0,006 с))) победа |
| Автор: ФедосеевПавел 10.10.2013, 21:52 |
| Если это возможно, покажи решение или расскажи, что за цикл добавляется. -------------- Также интересно, тест 18 не проходил по времени или по некорректным результатам? |
| Автор: Dmi3ev 10.10.2013, 22:26 | ||||||||
По времени не проходил, решение изначально верное... после оптимизации стало еще больше похоже... В третий цикл запихнул случай, когда дракон не каждый раз кого-то убивает... т. е. отдельно рассмотрел к=0. Сейчас уже вижу, что можно вывести формулу, но... задача уже решена) ср. время работы 0,002 с.
там ограничение до 10^9 в задаче... проверил кстати, у меня все работает в том варианте... ты что юзаешь??? Добавлено @ 22:31 PascalABC
GNU C++
|
| Автор: ФедосеевПавел 10.10.2013, 22:54 |
| Про зависание - наверное. я поторопился и где-то ошибся. Баловался Code::Block+MinGW == gnu c++ Поздравляю с найденым решением! |
| Автор: Mirkes 10.10.2013, 23:10 |
| Вообще-то задачу решал не я По поводу идей - есть. Скорее всего программа слишком долго ищет решение потому, что оценка нужного числа копейщиков слишком грубая от 1 до hd/dp. Если дракон слабенький но очень живучий (dh большое а dd маленькое) и копейщики тоже живучие но слабые, то число обменов ударами будет большое (много времени на проверку одного предполагаемого числа копейщиков) Учитывая заданный в задаче диапазон чисел вы вполне можете получить оценку типа 10^9: dh=10^9; dp=1; dd=10; hp=10; При этих условиях вы будете гонять порядка 30 рассчетов, причем при большом числе копейщиков каждый рассчет будет весьма долгим. Я посмотрел на правильный ответ потребуется 14142 тура. Представьте время, которое вам для этого потребуется Можно поробовать идти от числа туров при обмене ударами. [] - взятие целой части 1 тур N*dp=hd 2 тура 2N*dp-[dd/hp]*dp=hd 3 тура 3N*dp-[dd/hp]*dp-[2*dd/hp]*dp=hd и т.д. В каждом из этих уравнений нужно вычислить N и [k*dd/hp] Если второе значение станет больше первого, то проскочили и правильным ответом является N с предыдущего шага Если правильно организуете расчеты, то на каждом шаге нужно будет выполнить пару умножений и делений. Все операции только с целочисленными переменными. Полученный ответ может быть на 1 меньше, чем правильный. Это прийдется проверить путем прямого рассчета. Однако в этом случае число прямых рассчетов будет всего 2-3. А первичное вычисление N будет достаточно быстрым, поскольку в нем нет внутренних циклов. Успеха! |
| Автор: Dmi3ev 11.10.2013, 18:08 | ||
Mirkes, я уже решил задачу и выложил решение давно, смотри выше ) |