| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Object Pascal: кроссплатформенные технологии > Очень простая задача |
| Автор: Dr.Death 23.11.2004, 19:03 |
| Дано натуральное число Х. Найдите такое максимальное целое число, квадрат которого не превышает Х. Входные данные: Число Х(1<=Х<=10^1000) Выходные данные Число, удовлетворяющее условию Пример Вх. данные|Выходные 16 4 Значит не знаю только как представить себе число 10^1000, такого типа данных помойму вообще нет, а длинной арифметикой очень долго. Знаю, что вроде легко решается, ну а как? ограничения во времени 0,3с |
| Автор: Pakshin A. S. 23.11.2004, 19:14 | ||||
Вот-с.... Добавлено @ 19:20 А если подумав....
|
| Автор: dm9 25.11.2004, 22:16 |
| Pakshin A. S., а если значащих цифр больше 20? Возводим 111111111111111111111111111 в квадрат, полученное число скармливаем твоей программе. Она его урезает до 20 цифр (ну или сколько там) и выдаёт ответ: 111111111111111111111111110 или 111111111111111111111111109. Нет, без длинной арифметики никуда, имхо... Добавлено @ 22:18 PS calc.exe именно так и урезал - до 111111111111111111111111109... |
| Автор: Pakshin A. S. 25.11.2004, 22:20 |
| Нууу... Паскаль же не принимает большие числа... |
| Автор: dm9 25.11.2004, 22:21 |
| В данной постановке я бы посчитал, что задача нерешаема (с ограниченим времени) Добавлено @ 22:27 В худшем случае придётся придётся перемножить около 1600 чисел (500/lg(2)) с 500 знаками. Столько же операций сравнения. Сколько это по времени? Ну, это если использовать что-то типа деления отрезка пополам |
| Автор: Pakshin A. S. 25.11.2004, 22:40 |
| А как сохранить примерно вот такое число, которое должно быть введено (Х): 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - 1 Добавлено @ 22:40 Упс... Добавлено @ 22:41 Это же сколько пямять выделить надо? |
| Автор: Pakshin A. S. 25.11.2004, 22:54 |
| А что это мы с большими работам... давайте перейдем к бесконечно малым... Т. Е. будем работать с 1/х, где х - введённое с клавы число (надо придумать, как приобразовывать). Тогда ответ будет таким: хнаменатель дроби 1/trunc(sqrt(x)); Теперь надо будет только реализовать... |
| Автор: Pakshin A. S. 25.11.2004, 23:13 | ||
Вот... кое-что...
Может и не верно... простите... |
| Автор: dm9 25.11.2004, 23:29 | ||
| >Это же сколько пямять выделить надо? String[1000]. Много?
Та же фигня, разрядности не хватит... |
| Автор: cardinal 26.11.2004, 00:45 | ||
Вопрос: в каком виде они даны? |
| Автор: Dr.Death 26.11.2004, 18:12 | ||
Ну как в каком? Входные:16 Выходные:4 Там же все написано в начале - Число Х(1<=Х<=10^1000) |
| Автор: cardinal 26.11.2004, 18:15 | ||
Это и слону понятно, я имел в виду как они передаются процедуре, в виде массива или строки, как такое число передать функции? Тут идет речь о BigNumbers или нет? |
| Автор: Dr.Death 26.11.2004, 19:30 |
| cardinal Вообще по идее нам один чел говорил, который проверял задания, что он ее решит без BigNumbers. Насчет ввода я не знаю |
| Автор: Pakshin A. S. 26.11.2004, 19:34 |
| А может с памятью работать напрямую... Не знаю о чем только что сказал... но.... |
| Автор: dm9 26.11.2004, 20:02 |
| Dr.Death, спроси этого человека потом, как он это решил |
| Автор: Pakshin A. S. 26.11.2004, 20:16 |
| Млин... может тут какой-то подвох? |
| Автор: cardinal 26.11.2004, 22:15 |
| Ладно расскажу в какую сторону мыслил (я просто думал, что может что поточнее узнаю, но как видно нет Все числа от 1 до 10^1000 можно представить просто как значение их десятичного логарифма. То есть мы передаем функции не числа в диапазоне от 1 до 10^1000, а в диапазоне от 0 до 1000. Поделив число пополам мы и получим его корень Рассматривая числа 2, 62, 862, 5862, мы получаем: 0 + log2 + 0 = 0,3010 (соответствует 2) 1 + log6 + log(62/60) = 1,7924 (соответствует 62) 2 + log8 + log(862/800) = 2,9355 (соответствует 862) 3 + log5 + log(5862/5000) = 3,7680 (соответствует 5862) То есть наблюдается небольшая закономерность. Вопрос что делать дальше? Ладно, думайте! ... а то мне в splinter cell охото порубиться |
| Автор: dm9 26.11.2004, 23:33 |
| Математика, конечно, занимательная, но что отсюда следует - не пойму |
| Автор: cardinal 27.11.2004, 01:26 | ||
Ну с такими размышлениями можно добиться следующих результатов (четыре примера): X = 832193569 Предстваляем X в виде: 8 + log8 + log(8.321/8) = 8.9201 (округляем вниз) Корень X = 4.46005, то есть 10 ^ 4.46005 = 28843 (правильный ответ 28847) X = 6358120356 Предстваляем X в виде: 9 + log6 + log(6.358/6) = 9.8033 (округляем вниз) Корень X = 4.90165, то есть 10 ^ 4.90165 = 79735 (правильный ответ 79737) X = 4352362436567456 Предстваляем X в виде: 15 + log4 + log(4.352/4) = 15,6386 (округляем вниз) Корень X = 7,8193, то есть 10 ^ 7,8193 = 65962939 (правильный ответ 65972436) А что делать? X = 10 ^ 1000 = 10000000... Предстваляем X в виде: 1000 + log1 + log(1.000/1) = 1000 Корень X = 500, то есть 10 ^ 500= 100000000... (правильный ответ именно такой же На самом деле я думаю, что тут если еще немного покумекать, то можно какой-нибудь рекурсивный алгритм придумать, которую за n-ое выполнение самого себя, улучшит результат. |
| Автор: dm9 27.11.2004, 16:20 |
| Просто всё равно мы приходим к логарифму, у которого 20 значащах цифр. Недостаточно для описания целого числа из 1000 знаков... Хотя, может, я чего не понял |
| Автор: cardinal 27.11.2004, 17:05 | ||||
У меня же нет 20 значащих цифр... Вопрос в точности...
Я о том и говорю, что "осталось лишь" придумать как улучшить это значение логарифма. Сейчас точность с 10-ти значными числами неплохая, но 16-ти значное число уже дает погрешность в 0.015 процента, что немного, но так как число большое, то от правильного результата мы улетаем далеко... |
| Автор: Fedor 29.11.2004, 18:48 |
| Ребят... Почитал я тут... По-моему, вы не в ту сторону зашли. Есть же алгоритм извелечения квадратного корня из числа (я его правда не помню - сейчас поищу). Работает он со сложностью по-моему n, где n - количество разрядов. Берем тогда это число входное число, извлекаем из него корень "с остатком" и задача решена. Попробую сейчас найти алгоритм и наваять программу. З.Ы. По-моему, этой теме место в Vingrad-колледж Добавлено @ 18:53 Ну вот например Яндексом быстро нашел. http://www.pspu.ac.ru/mirrors/computer-science/DL-AR/koren.html Сейчас напишу программу. |
| Автор: Fedor 29.11.2004, 21:58 | ||
Фух. Весь вечер пропарился. Давно не программировал такие задачки...
Надеюсь, что-то поймете. Я позже прокомментирую строчки. Чтоб понятнее было. Сейчас просто времени уже не осталось. На максимальном тесте работает около секунды. Хотя уверен можно оптимизировать (например хранить длинные числа не по одному разряду, а по два или больше. А может и сам алгоритм подправить) |
| Автор: cardinal 29.11.2004, 22:00 |
| Morpheus, все это хорошо, но во-первых как решить задачу в заданное время, а во-вторых как ты представишь корень числа 10^1000? Я пока это не понимаю... |
| Автор: Fedor 29.11.2004, 22:18 | ||||
Именно этим способом. Я уверен. Только нужно немного упростить мое решение. А то сейчас оно у меня тупо в лоб делает арифметические действия. Скорее всего, можно упростить где-то. |
| Автор: cardinal 29.11.2004, 22:27 | ||
Ну тогда держи +. Как говорится все гениальное просто - мне понравился алгоритм (см. ссылка) |
| Автор: dm9 29.11.2004, 23:24 |
| Morpheus, ты каким компилятором пользовался? У меня в трёх местах английская "С" заменена на русскую... При вводе (10^n)^2, где n - любой целое (например, 10000) - Access violation... Может, дело в том, что я Delphi использую... А вообще, идея интересная |
| Автор: cardinal 29.11.2004, 23:35 | ||
Ограничение в 10^1000, ты о чем? |
| Автор: dm9 29.11.2004, 23:57 |
| Я о том, что когда я пытаюсь скормить программе число, корень из которого - единица с последующими нулями, у меня вылетает AV... Это Borland Pascal был? Надо будет в нём попробовать запустить... |
| Автор: S.A.P. 29.11.2004, 23:58 |
| Может не обязательно число представлять с высокой точностью, а в виде 2-х воставляющих как в условии. Например число 10 - как 10 и 1, а число 5^100 как 5 и 100? |
| Автор: dm9 30.11.2004, 00:09 |
| Perchilla, так не интересно |
| Автор: cardinal 30.11.2004, 00:09 | ||
То есть корень от (10^10000)^2 это единица с последующими нулями Perchilla, ты еще идею не понял см. еще раз http://www.pspu.ac.ru/mirrors/computer-sci...L-AR/koren.html |
| Автор: dm9 30.11.2004, 00:13 |
| cardinal, там пример не совсем корректен 10000 - это не n. n здесь равно двум (10^2)^2 = 10000 - корень из этого числа равен 100, то есть единица с нулями Вот ввожу я 10000, 1000000, 1000000000000000000000000000000000000 и получаю AV... |
| Автор: cardinal 30.11.2004, 00:48 |
| Теперь понятно, а то n, n... |
| Автор: Fedor 30.11.2004, 01:11 |
| dm9 Прав.... Молодец. Я то и не тестировал почти совсем. Обрадовался было уже, что на рендомических тестах работает. Забыл уже, как на олимпиадах заваливают. Ну, я подправил в некоторых местах. Начал тестировать - еще нашел неправильный ответ. Исправил вроде (я неправильно единицу к числу прибавлял в самом конце, например). Насчет русских букв C - это форум позаменял © на значки копирайтов. Ну, я их обратно редактировал да видно раскладку клавиатуры забыл поменять. Сорри. В общем, ловите: |