Задания
Версия для печати и копирования в MS Word
Тип 16 № 62468
i

Ал­го­ритм вы­чис­ле­ния зна­че­ния функ­ции F(n), где n  — целое число, задан сле­ду­ю­щи­ми со­от­но­ше­ни­я­ми:

F левая круг­лая скоб­ка n пра­вая круг­лая скоб­ка = n, если n мень­ше 10,

F левая круг­лая скоб­ка n пра­вая круг­лая скоб­ка = F левая круг­лая скоб­ка n mod 10 пра­вая круг­лая скоб­ка плюс F левая круг­лая скоб­ка n div 10 пра­вая круг­лая скоб­ка , если n боль­ше = 10.

 

Опре­де­ли­те ко­ли­че­ство зна­че­ний n, мень­ших 263, для ко­то­рых F левая круг­лая скоб­ка n пра­вая круг­лая скоб­ка = 159.

Спрятать решение

Ре­ше­ние.

При­ведём ре­ше­ние на языке Python.

from functools import *

# гра­нич­ное зна­че­ние

a = list(map(int, str(2**63-1)))

@lru_cache(None)

def f(s, l, fl):

# если по­сле­до­ва­тель­ность нуж­ной длины, про­ве­ря­ем, что сумма нам под­хо­дит,

# и вы­хо­дим из ре­кур­сии.

if l == 0: return s == 159

# про­ве­ря­ем огра­ни­чен­ные под­по­сле­до­ва­тель­но­сти боль­шей длины

return sum(f(s+x, l-1, fl and (x == a[-l])) for x in range([10, a[-l]+1][fl]))

# ответ - ко­ли­че­ство огра­ни­чен­ных по­сле­до­ва­тель­но­стей не­об­хо­ди­мой длины

print(f(0, len(a), 1))

 

Ответ: 34602572.

 

При­ведём ва­ри­ант при­ве­ден­но­го ре­ше­ния от Юрия Кра­силь­ни­ко­ва на языке Python с ком­мен­та­ри­я­ми.

import functools

гра­ни­цы = list(map(int,str(2**63-1)))

# гра­ни­цы - это де­ся­тич­ные цифры числа 2**63-1. Мы не долж­ны пре­вы­шать это число.

@functools.lru_cache(None)

# Ор­га­ни­зу­ем кэш для того, чтобы из­бе­жать по­втор­ных пе­ре­вы­чис­ле­ний функ­ции

def f(сумма, по­зи­ция, на_пре­де­ле):

# сумма - ча­стич­ная сумма цифр числа

# по­зи­ция - по­зи­ция оче­ред­ной цифры, ко­то­рую мы пе­ре­би­ра­ем

# на_пре­де­ле - это ло­ги­че­ская пе­ре­мен­ная. Зна­че­ние «ис­ти­на» озна­ча­ет, что все преды­ду­щие цифры -

# «на пре­де­ле» и по­это­му те­ку­щая цифра тоже не долж­на пре­вы­шать гра­ни­цу для неё.

# «Ложь» - слева есть цифры менее пре­дель­ных и по­это­му те­ку­щая цифра может быть любой

if по­зи­ция == len(гра­ни­цы): # мы до­стиг­ли мак­си­маль­но воз­мож­ной длины числа

return 1 if сумма == 159 else 0 # воз­вра­ща­ем 1, если по­лу­чи­лась нуж­ная сумма цифр

пре­дел = (гра­ни­цы[по­зи­ция] if на_пре­де­ле else 9)+1

# если «на пре­де­ле» - пе­ре­би­ра­ем цифры до гра­ни­цы, иначе - все цифры

return sum(f(сумма+цифра,по­зи­ция+1,на_пре­де­ле and цифра==гра­ни­цы[по­зи­ция]) for цифра in range(пре­дел))

# сум­ми­ру­ем ре­зуль­та­ты для всех воз­мож­ных сле­ду­ю­щих цифр

print(f(0,0,True)) # на­чи­на­ем с по­зи­ции 0, и пер­вая (стар­шая) цифра не долж­на пре­вы­шать гра­ни­цу


Аналоги к заданию № 62468: 62470 Все

Источник/автор: Семён Чайкин