Digprime.py — различия между версиями

Материал из DISCOPAL
Перейти к: навигация, поиск
(Новая страница: «<source lang="python"> # globals input_str = "" dp = [[[-1, -1], [-1, -1]] for i in range(25)] def calculate(i, taken: int, ls: int) -> int: global input_…»)
 
 
(не показано 8 промежуточных версий этого же участника)
Строка 1: Строка 1:
 
<source lang="python">
 
<source lang="python">
 +
import sys
 +
 +
digits = 19
 
# globals
 
# globals
 
input_str = ""
 
input_str = ""
dp = [[[-1, -1], [-1, -1]] for i in range(25)]
+
dp = [[[-1, -1], [-1, -1]] for i in range(digits)]
 +
N = None
 
   
 
   
 +
 +
def get_input():
 +
    lines = sys.stdin.readlines()
 +
    content = " ".join(lines).strip()
 +
    for token in content.split():
 +
        yield token
 +
 +
tc_ = get_input()
 +
next(tc_)
 +
 +
p10 = [10**i for i in range(digits)]
 +
 
   
 
   
 
def calculate(i, taken: int, ls: int) -> int:
 
def calculate(i, taken: int, ls: int) -> int:
 +
    '''
 +
    i — индекс цифры
 +
    taken — встречали ли простые цифры раньше
 +
    ls — в текущем индексе можно делать полный перебор
 +
    '''
 
     global input_str
 
     global input_str
 
     global dp
 
     global dp
     if i == len(input_str):
+
     global N
        return taken
+
 
    if dp[i][taken][ls] != -1:
+
        return int(dp[i][taken][ls])
+
 
     res = 0
 
     res = 0
 
     if ls:
 
     if ls:
Строка 17: Строка 36:
 
     else:
 
     else:
 
         limit = int(input_str[i])
 
         limit = int(input_str[i])
 +
 
     for x in range(limit + 1):
 
     for x in range(limit + 1):
         res += calculate(i + 1, taken | (x == 2) | (x == 3) | (x == 5) | (x == 7), ls | (x != limit))
+
         newtaken = taken or (x == 2) or (x == 3) or (x == 5) or (x == 7)
 +
        newls = ls or (x != limit)
 +
        newi = i + 1
 +
 
 +
        if newi == N:
 +
            ret = newtaken
 +
        elif newls and newtaken:
 +
            ret = p10[N - newi]
 +
        else:
 +
            cached = dp[newi][newtaken][newls]
 +
            if cached != -1:
 +
                ret = cached
 +
            else:
 +
                ret = calculate(newi, newtaken, newls)
 +
 
 +
        res += ret
 
   
 
   
     dp[i][taken][ls] = int(res)
+
     dp[i][taken][ls] = res
     return int(res)
+
     return res
 
   
 
   
 
   
 
   
test_count = int(input())
+
for input_str in tc_:
for i in range(test_count):
+
     N = len(input_str)
     input_str = input()
+
     for j in range(digits):
     for j in range(25):
+
 
         dp[j][0][0] = -1
 
         dp[j][0][0] = -1
 
         dp[j][1][0] = -1
 
         dp[j][1][0] = -1

Текущая версия на 02:33, 1 мая 2022

import sys
 
digits = 19
# globals
input_str = ""
dp = [[[-1, -1], [-1, -1]] for i in range(digits)]
N = None
 
 
def get_input():
    lines = sys.stdin.readlines()
    content = " ".join(lines).strip()
    for token in content.split():
        yield token
 
tc_ = get_input()
next(tc_)
 
p10 = [10**i for i in range(digits)]
 
 
def calculate(i, taken: int, ls: int) -> int:
    '''
    i — индекс цифры
    taken — встречали ли простые цифры раньше
    ls — в текущем индексе можно делать полный перебор
    '''
    global input_str
    global dp
    global N
 
    res = 0
    if ls:
        limit = 9
    else:
        limit = int(input_str[i])
 
    for x in range(limit + 1):
        newtaken = taken or (x == 2) or (x == 3) or (x == 5) or (x == 7)
        newls = ls or (x != limit)
        newi = i + 1
 
        if newi == N:
            ret = newtaken
        elif newls and newtaken:
            ret = p10[N - newi]
        else:
            cached = dp[newi][newtaken][newls]
            if cached != -1:
                ret = cached
            else:
                ret = calculate(newi, newtaken, newls)
 
        res += ret
 
    dp[i][taken][ls] = res
    return res
 
 
for input_str in tc_:
    N = len(input_str)
    for j in range(digits):
        dp[j][0][0] = -1
        dp[j][1][0] = -1
        dp[j][1][1] = -1
        dp[j][0][1] = -1
    print(calculate(0, 0, 0))