計算幸運數字的個數
阿新 • • 發佈:2018-12-11
我們稱一個長度為n的數X(X= d1d2......dn, d1 != 0)為幸運數,當且僅當,對於所有的, 滿足di != d(n+1-i),請問在[a, b]之間存在多少幸運數:
分析:
只需計算x<= b 以及< a分別有多少個幸運數即可。
對於數字b(假設b的位數是n, 每一位數字存在資料data[n]中,下標以1開始)
示例:
b = 2999
則 n = 4, data = [-1, 2, 9, 9, 9]
則對於b需要求得分為4部分:
1. 所有一位數字中的幸運數 f(1) =9
2. 所有兩位數字中的幸運數:f(2)= 81
3. 所有三位數字中的幸運數 f(3) =810
4. 1000-2999之間的幸運數
定義f(n) 為所有n位數中幸運數字個數,對於 1,2, 3 ,部分當數字為 n的時候 很容易有遞推公式
f(n) = 9*(f(n-2)+f(n-4)*9+...+f(n-2^i)*9^(i-1) + f(0)*9^(n/2-1))*9, n>= 4,f(0) = 1, n 為偶數
簡單理解就是 對於數字 d1d2......dn, d1和dn 都有 9 種取法,假設cnt(num) 是求num的數字個數,則
f(cnt(d1d2....dn)) = 9*9*(d2!= 0 的時候的個數+d2==0的個數)= A+B
A = f(cnt(d2...dn-1)
B = (d3!= 0 的時候的個數+d3==0的個數)以此內推
對於第四部分:
1000-2999之間
一個迴圈求得:
res = 0
i = 1, res+= (data[1]-1)*(A+B)
for i in range(2, n + 1): if(data[i]==0): break if(i <= (n // 2)): res += data[i] * f(n - 2 * i) * (9 ** (i + 1)) continue if(n%2 == 1 and i == n//2 + 1): res += data[i]*(9**i) continue else: if(data[n+1-i] >= data[i]): res += data[i]*9**(n - i) else: res += (data[i]-1)*9**(n - i)
具體程式碼見下面(關於A+B的程式碼計算部分有待修改):
a, b = [int(x) for x in input().split()]
def f(n):
if (n == 0):
return 1
if(n == 1):
return 9
if(n == 2):
return 81
if(n == 3):
return 810
else:
return 81*(f(n-2)+f(n-4)*9)
def get_data(b):
cnt = 0
data = []
while(b>0):
data.append(b%10)
b = b // 10
cnt += 1
data.append(-1)
data.reverse()
return (cnt, data)
def isluck(data, n):
find = True
for i in range(1, n // 2+1):
if (data[i] == data[n + 1 - i]):
find = False
break
return find
def count(n, data, b):
res = 0
if(n >= 4):
res += (data[1]-1) * (f(n - 2) + f(n - 4) * 9) * 9
if(n == 3):
res += (data[1]-1) * (f(n - 2) + f(0)) * 9
if(n == 2):
res += (data[1] - 1)*9
if(n == 1):
res += data[0]
return res
for i in range(2, n + 1):
if(data[i]==0):
break
if(i <= (n // 2)):
res += data[i] * f(n - 2 * i) * (9 ** (i + 1))
continue
if(n%2 == 1 and i == n//2 + 1):
res += data[i]*(9**i)
continue
else:
if(data[n+1-i] >= data[i]):
res += data[i]*9**(n - i)
else:
res += (data[i]-1)*9**(n - i)
if(isluck(data, n)):
res += 1
for i in range(1, n):
res += f(i)
return res
cnt_b, data_b = get_data(b)
cnt_a, data_a = get_data(a-1)
res_b = count(cnt_b, data_b, b)
res_a = count(cnt_a, data_a, a-1)
print(res_b-res_a)