![]() |
Модераторы: Alx, Fixin |
![]() ![]() ![]() |
|
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 2 Всего: 30 |
Решаю заочную олимпиаду по информатике. Упор делается на неординарность решения, нестандартность алгоритма и т.п..
Одна из задач:
В паскале есть оператор выделения кол-ва десятков, сотен и т.п. или оператор выделения цифры, стоящей на первой, второй, третьей и т.д. позиции? ![]() ![]() ![]() |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 3 Всего: 459 |
Нет нужно делить число на 10 (целочисленое деление div 10) и брать остаток от целочисленого дления (mod 10), остаток дает очередную цифру. Затем операция повторяется уже над числом разделенным на 10. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 2 Всего: 30 |
alexeis1, спасибо.
![]() Таким образом, у меня получилось следующее: Примечания: m - число M ("... найти сумму всех целых чисел от 1 до M ...); s - сумма всех целых чисел от 1 до M; r - результат целочисленного деления на 10 одного из чисел, принадлежащих [1; M]; o - остаток от целочисленного деления на 10 одного из чисел, принадлежащих [1; M] i - переменная для [1; M]. Операторы вывода опускаю. ![]()
Только мне кажется, что такой алгоритм не может претендовать на неординарность, экзотичность и т.д.. ![]() ![]() ![]() Если у вас есть какие-то свои алгоритмы и мысли, то, пожалуйста, поделитесь. ![]() ![]() |
|||
|
||||
Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: нет Всего: 37 |
Есть такая мысль - держать текущее число в качестве массива - array[1..10] of byte. Самому сделать операцию прибавления единицы(это очетнь просто). Тогда подсчет сведется к простомму суммированию элементов массива.
|
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 3 Всего: 459 |
Но тогда все равно прийдется проделывать ту же самую операцию для полученя цифр числа. KasMP, это и правду самый класический, пример, но проблема в том, что числа то хранятся в двоичной системе счисления, а нужна десятичная. Эта операция делает ни что иное как обычный перевод из двоичной в десятичную систему счисления. Как альтернатива использование двоично-десятичного представления чисел (того которое используется в калькуляторах). При этом каждая 10 - чная цифра записывается ввиде 4 бит байта. В этом случае получение цифры сводится к простейшей операции сдвига на 4 разряда. Но паскаль не поддерживатет работу с такими числами, тут надо лезть в ассемблер. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
KasMP |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 2 Всего: 30 |
Видимо, я чего-то не знаю, но мне всегда казалось, что держать одно число в массиве из 10 элементов невозможно. Ведь число одно, а элементов 10 (т.е., конечно, можно оставить 9 ячеек массива пустыми и выбрать какую-то одну (так тогда имхо проще просто использовать переменную, а не целый массив), но как можно одно число описать через 10 элементов???). Или для описания десятичного числа через числа типа byte необходимо несколько чисел (цифр?) типа byte? (извините за тафтологию, но более понятно сказать не получается). Или как? ![]()
Ты бы не мог привести пример для наглядности? ![]() _______________________________________________
Эм... А от паскаля до ассемблера очень далеко? Или они, так сказать, братья по крови? ![]() ![]() |
||||||
|
|||||||
Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: нет Всего: 37 |
Извините если че не так... давно на паскале не писал
|
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 2 Всего: 110 |
паскаль поддерживает работу с массивами/структурами и позволяет их обрабатывать с помощью функций этого вполне достаточно, чтобы не задумываться об ассемблере в данном случае касательно задачи в целом: 1. если число меньше 10 - всё понятно, n*(n-1)/2 2. если число больше 9, но меньше 100, можно попробовать так: разбиваем весь отрезок 1..N на отрезки с одинаковыми старшими цифрами и считаем их отдельно получится куча полных отрезков из 10 элементов (например, 20,21,22,23,24,25,26,27,28,29) и один неполный - там, где находится заданная граница подсчитать сумму цифр в полном отрезке легко: считаем сумму старших цифр (т.е просто умножаем её на 10) и сумму младших (т.е. просто записываем 9*(9-1)/2) в неполном отрезке особо можно и не заморачиваться - считаем простым способом ну а дальше можно развивать этотподход на трёх- и более значные числа... -------------------- qqq |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 3 Всего: 459 |
Оч. далеко ![]() ![]() -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 2 Всего: 30 |
Спасибо за пример. ![]() Но, к сожалению, пока мне не хватает знаний/умений/опыта для понимания твоей мысли (не знаю, что такое inc; плохо понимаю тип byte и т.д.). (маленькая опечаточка есть: после if всегда следует then) __________________________________________________________ maxim100, спасибо за участие. ![]() Похожая мысль меня посещала... И я была вынуждена отказаться от нее по след.причинам: а) числом N теоретически вполне может оказаться 10 в очень большой степени. Прописать варианты для промежутков 10<=n<100, 100<=n<1000, 1000<=n<10000 и т.д. не представляется возможным, т.к множество чисел бесконечно (или в некотором смысле конечно? я где-то слышала, что максимальное число, которым может оперировать паскаль при типе integer немного больше 30000) (не знаю, может, можно как-то автоматизировать этот процесс: выделить степень числа (если число 12453 (т.е. 10000+2453), то его степень - 4), обозначить эту степень чем-нибудь и потом до тех пор, пока степень не станет равна 1 (или нулю?), выполнять некоторые операции; но пока не знаю, надо еще подумать...); б) необходимо делить программу на 2 части: на, как выразился maxim100, полные отрезки и на остаток; в) необходимо создавать механизм, определяющий, когда пора завершать считывание полных отрезком и приниматься за остаток. Хотя, с точки зрения неординарности этот подход, наверно, смотрится очень даже неплохо. ![]() |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 3 Всего: 459 |
inc(i); тоже что и i := i + 1; только быстрее работает byte - это тот же integer но беззнаковый и более маленький - значения (0..255) А на счет if - это проблема всех кто пишет на C++ (там этого нет) -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 2 Всего: 110 |
касательно диапазонов: если число не выходит за пределы 16 бит, достаточно рассмотреть 5 степеней (32 бита - не более 10), дальше - арифметика длинных чисел
с точки зрения автоматизации всего этого мысли тут такие: вводим число An - сумма цифр всех чисел от 0 до (10^n)-1 теперь берём число x и начинаем его обрабатывать: ---1.для начала разбиваем его на старшую часть (старшая цифра и нули) - y и младшую часть (все цифры кроме старшей) - z для x=3456 y=3000, z=456 ---2.считаем сумму цифр чисел от 0 до y-1 ну точнее не считаем, а используем знание чисел An: для y=3000 s[0..2999]=s[0..999]+s[1000..1999]+s[2000..2999]=A3+1*1000+A3+2*1000+A3 для общего случая получается An*d+10^n*(0+1+2+...+d-1)=An*d+10^n*d*(d-1)/2 d - старшая цифра n - её порядок (тут надо с бумажкой посидеть и проверить - мог напутать) ---3.считаем сумму цифр от y до x (=y+z) s[3000..3456]=456*3+s[0..456] ну или для общего случая: s[y..y+z]=z*d+s[0..z] ну а s[0..z] считаем рекурсивно этой же функцией, а его порядок уже на 1 меньше (екурсивный вызов будет в конце, так что можно потом будет без проблем переделать в цикл, если надо) подсчёт An - тоже рекурсивный: An=S[0..(10^n)-1]=s[0..1*(10^(n-1))-1]+s[1*(10^(n-1))..2*(10^(n-1))-1]+...= (1+2+3+4+5+6+7+8+9)*10^(n-1)+10*A[n-1] т.е. можно прямо перед подсчётом вычислить массив нужных An (количество посмотреть по порядку числа), и использовать его потом его размер логарифмический, что часто приемлимо в принципе, если сильно надо, можно изменить порядок рекурсии и считать, начиная с младших частей, тогда можно будет обойтись даже без массива, но это уже дальнейшая оптимизация... -------------------- qqq |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 2 Всего: 30 |
Хорошие новости: сегодня узнала, что можно ограничить число M удобным мне множеством [1; N].
![]() В таком случае, ничего лучше, чем деление числа на полные отрезки и остаток ![]()
Но потом, когда доделаю до конца олимпиаду и смогу спокойно, в размеренном ритме, никуда не торопясь, думать, то обязательно попробую "автоматизировать" процесс считывания степени т.д. (уж очень интересно попробовать ![]() |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Интересные и занимательные задачи по программированию | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |