Среди задач соревнования по программированию есть задача на цифровой палиндром. Требуется найти количество палиндромов в заданном интервале. Все участники решают ее в лоб. То есть перебирают все числа и проверяют их на совпадение со своей обратной записью. Диапазон чисел, которые указаны в задании позволяют найти ответ за нужное время. А если диапазон значительно увеличить ? Я набросал небольшой код, который позволяет решить такую задачу очень быстро. Приведу его.
Функция ПалиндромРекурсия(лев,прав,цифры)
если лев>прав тогда
если цифры[лев] < цифры[прав] тогда
возврат 0;
иначе
возврат 1;
конецесли;
иначеесли лев=прав тогда
если цифры[лев-1] > цифры[прав+1] тогда
возврат цифры[лев];
иначе
возврат цифры[лев]+1;
конецесли;
конецесли;
счетчик=0;
//здесь мы вычисляем количество палиндромов, которые образуют цифры
//на интервале (лев,прав) это степень 10
интервал=Цифры.ВГраница()-лев-лев;
если интервал%2=0 тогда
с=Pow(10,интервал/2);
иначе
с=Pow(10,(интервал+1)/2);
конецесли;
цифраЛев=?(лев=1,1,0);
цифраПрав=цифры[лев]-1;
если цифраЛев<=цифраПрав тогда
счетчик=с*(цифраПрав-цифраЛев+1);
конецесли;
счетчик=счетчик+ПалиндромРекурсия(лев+1,прав-1,цифры);
возврат счетчик;
КонецФункции
//9 9 90 90 900 900
//9*(1+1+10+10+100+100) =2*(9+90+900)
//2*(999)
Функция Палиндром(Н) экспорт
если Н<10 тогда
Результат=Н;
иначе
//длина входного числа минус 1
д=СтрДлина(xmlСтрока(Н))-1;
//найдем количество палиндромов в интервале 1 .... 10^(д)-1
//это количество зависит от четности числа д
//если д четное, то это количество равно 2*(10^(д/2)-1)
//если д нечетное, то это количество равно 2*(10^((д-1)/2+1)-1)-9*10^((д-1)/2)=11*10^((д-1)/2)-2
если д%2=0 тогда
Результат=2*(Pow(10,д/2)-1);
иначе
Результат=11*Pow(10,(д-1)/2)-2
конецесли;
// нашли кличество палиндромов в интервале 1...99999
// теперь ищем в интервале 10000... Н
// для этого анализируем цифры в числе Н
цифры=новый массив;
стр=xmlСтрока(Н) ;
д=СтрДлина(стр) ;
цифры.Добавить(0) ;
для i=1 по д цикл
цифры.Добавить(число(Сред(стр,i,1)));
конеццикла;
Результат=Результат+ПалиндромРекурсия(1,д,цифры);
конецесли;
сообщить(Результат);
КонецФункции
Показать
Для диапазона 1..134354657688783400454532323989090343434343411
Программа дает ответ 23 435 465 768 878 340 045 451