MAX = 20
set = []
m = 5
n = 3
for i in range(m):
set.append(i + 1)
for i in range(n):
print('{} '.format(set[i]), end='')
print('')
position = n - 1
while True:
if set[n - 1] == m:
position -= 1
else:
position = n - 1
set[position] += 1
for i in range(position + 1, n):
set[i] = set[i - 1] + 1
for i in range(n):
print('{} '.format(set[i]), end='')
print('')
if set[0] >= m - n + 1:
break
首先我们来看一下数字拆解方式:
3的拆法:3 = 2+1 = 1+1+1
4的拆法:4 = 3 + 1 = 2 + 2 = 2 + 1 + 1 = 1 + 1 + 1 + 1
5的拆法:5 = 4 + 1 = 3 + 2 = 3 + 1 + 1 = 2 + 2 + 1 = 2 + 1 + 1 + 1 = 1 + 1 +1 +1 +1
依次类推,给出一个数字num拆解方法个数是多少?
以5的拆法为例,假设数字n的拆法有f(n)个,使用f(x,y)为使用y以下的数字来拆解x的方法个
数,则:
f(5) = f(4, 1) + f(3,2) + f(2,3) + f(1,4) + f(0,5),其中f(1, 4) = f(1, 3) + f(1, 2) + f(1, 1),但是使
用1的数字来拆解1没有意义,所以f(1, 4) = f(1, 1),而同样的,f(0, 5)会等于f(0, 0),所以:
f(5) = f(4, 1) + f(3,2) + f(2,3) + f(1,1) + f(0,0) 依照以上的说明,使用动态程式规画(Dynamic
programming)来进行求解,其中f(4,1)其实就是f(5-1, min(5-1,1)),
f(x, y)就等于f(n-y, min(n-x, y)),其中n为要拆解的数字,而min()表示取两者中较小的数。
实现如下:
NUM = 5
DEBUG = 0
table = [[0 for _ in range(NUM // 2 + 1)] for _ in range(NUM)]
count = 0
result = 0
print("数字拆解")
print("3 = 2+1 = 1+1+1 所以3有三种拆法")
print("4 = 3 + 1 = 2 + 2 = 2 + 1 + 1 = 1 + 1 + 1 + 1")
print("共五种")
print("5 = 4 + 1 = 3 + 2 = 3 + 1 + 1")
print(" = 2 + 2 + 1 = 2 + 1 + 1 + 1 = 1 + 1 +1 +1 +1")
print("共七种")
print("依此类推,求 {} 有几种拆法?".format(NUM))
for i in range(NUM):
table[i][0] = 1 # 任何数以0以下的数拆解必只有1种
table[i][1] = 1 # 任何数以1以下的数拆解必只有1种
for i in range(2, NUM+1):
for j in range(2, i+1):
if i+j > NUM:
continue
count = 0
for k in range(1, j+1):
if i-k >= k:
s = k
else:
s = i-k
count += table[i-k][s]
table[i][j] = count
for k in range(1, NUM+1):
if NUM-k >= k:
s = k
else:
s = NUM-k
result += table[NUM-k][s]
print("result: {}".format(result))
假设老师按照学生的学号输入成绩,现希望在输入完毕后自动显示学生分数的排行。
这里我们使用数组来帮助我们快速排序。
实现如下:
MAX = 100
MIN = 0
juni = [0 for _ in range(MAX+3)]
i = 0
score = [100,90,80,95,93,85,80,-1]
count = 6
for i in range(count):
juni[score[i]] += 1
juni[MAX+1] = 1
for i in reversed(range(MIN, MAX+1)):
juni[i] = juni[i] + juni[i+1]
print("得分\t排行")
for i in range(count):
print("{}\t{}".format(score[i], juni[score[i]+1]))
为了节省空间或是方便计算,很多时间我们会选择使用一维矩阵存储多维矩阵。以二维矩阵
转一维矩阵为例,索引值由0开始,在由二维阵列转一维阵列时,我们有两种方式:「以列
(Row)为主」或「以行(Column)为主」。以列为主的二维阵列要转为一维阵列时,是将二维
阵列由上往下一列一列读入一维阵列,此时索引的对应公式如下所示,其中row与column是二维阵
列索引,loc表示对应的一维阵列索引:
实现如下:
arr1 = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]]
arr2 = [0]*12
print("原二维矩阵:")
for row in range(3):
for col in range(4):
print("{} ".format(arr1[row][col]),end="")
print("")
print("第一种:")
for row in range(3):
for col in range(4):
i = col + row * 4
arr2[i] = arr1[row][col]
for i in range(12):
print("{} ".format(arr2[i]),end="")
print("")
print("第二种:")
for row in range(3):
for col in range(4):
i = col * 3 + row
arr2[i] = arr1[row][col]
for i in range(12):
print("{} ".format(arr2[i]),end="")
实现如下:
N = 6
def swap(x, y):
t = x
x = y
y = t
def magic_o(square, n):
row = 0
column = n // 2
for count in range(1, n*n+1):
square[row][column] = count
square[row+n][column+n] = count + n*n
square[row][column+n] = count + 2*n*n
square[row+n][column] = count + 3*n*n
if count%n == 0:
row += 1
else:
if row == 0:
row = n-1
else:
row = row - 1
if column == n-1:
column = 0
else:
column = column + 1
def exchange(x, n):
m = n // 4
m1 = m - 1
for i in range(n//2):
if i != m:
for j in range(m):
swap(x[i][j], x[n//2+i][j])
for j in range(m1):
swap(x[i][n-1-j], x[n//2+i][n-1-j])
else:
for j in range(m+1):
swap(x[m][j], x[n//2+m][j])
for j in range(m1):
swap(x[m][n-1-j], x[n//2+m][n-1-j])
if __name__ == "__main__":
square = [[0 for _ in range(N)] for _ in range(N)]
magic_o(square, N//2)
exchange(square, N)
for i in range(N):
for j in range(N):
print("{} ".format(square[i][j]), end="")
print('')