为了纪念我终于看懂了k好数这题是什么意思,特此留念。(hhhhh)
题目:如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数。求L位K进制数中K好数的数目。例如K = 4,L = 2的时候,所有K好数为11、13、20、22、30、31、33 共7个。由于这个数目很大,请你输出它对1000000007取模后的值。
输入L和K
K表示K进制(就是二进制、十进制这种,我一开始这都没看懂!!!)所以4进制就是0-3组成的数。
2位数,就很好理解两位数嘛
但我们都知道两位数可以由一位数构成:
如果我们定义一个数组list_[j],j表示个位数的数值,list_表示个数的话就可以有下面这个表:
j
0
1
2
3
list_
1
1
1
1
然后我们在用一位数组成我们需要的两位数
十位\个位
0
1
2
3
0
0
1
2
3
1
10
11
12
13
2
20
21
22
23
3
30
31
32
33
首先,首位为0的数不是两位数,我们先全部排除。那么我们只要看下面三行。
首位为1的数有10,11,12,13,把具有相邻两位的10和12排除,剩下11和13。因为首位是确定的,所以只要看个位,相当于第一个表格中1和3的个数list_加起来就是这一行的总数。
以此类推以2位首位的数字排除21和23,剩下20和22。首位确定只看个位,就是把0和2的list_加起来
总结一下,不相邻就是十位和个位的差不等于1,即只要把个位和十位相差不为1的list_加起来就可以。最后把所有十位数确定的加起来。
往下递推三位数列表
00
01
02
03
10
11
12
13
20
21
22
23
30
31
32
33
0
000
001
002
003
010
011
012
013
020
021
022
023
030
031
032
033
1
100
101
102
103
110
111
112
113
120
121
122
123
130
131
132
133
2
200
201
202
203
210
211
212
213
220
221
222
223
230
231
232
233
3
300
301
302
303
310
311
312
313
320
321
322
323
330
331
332
333
因为我们第一次循环已经得出了两位数的个数,所以同样只要比较首位和次位的差,按照前面的方法累加就可以了
这样我们就需要两个变量来确定一个数组,i 表示这是几位数,j 表示首位的值。设list_[ i ][ j ]
代码如下:
k,l = [int(i) for i in input().split()]
mod = 1000000007
list_ = list()
for i in range(l+1):
list_.append([])
for j in range(k):
list_[i].append(0)
for i in range(k):
list_[1][i] = 1 #一位数全部都是一个
for i in range(2, l+1): #从二位数开始计算
for j in range( k): #相当于两位数中的十位
for m in range(k): #相当于两位数中的个位
if abs(j-m) != 1: #排除十位和个位差为一的数
list_[i][j] = (list_[i][j]+list_[i-1][m]) % mod #将剩下的数相加取余
print(list_[i][j])
ans = 0
for i in range(1,k): #排除首位为0的数
ans = (ans + list_[l][i]) % mod 将L为所有首位的数求和取余
print (ans)
搬运自https://blog.csdn.net/libin56842/article/details/19910663