如何求正整数n的所有可能的整数组合
例如: 4=1+1+1+1, 1+1+2, 1+3, 2+2, 4, 还要按递增展示,
嗯嗯, 懵逼
def printResult(result, count):
if not result:
return
size = len(result)
if count < 0 or count > size:
return
# 这里只有从0到count-1位才是结果
temp = ""
for i in range(0, count):
if temp:
temp += "+" + str(result[i])
else:
temp = str(result[i])
print(temp)
'''
sums:求和为sums的所有组合
result:结果数组
count:组合中数字的个数
'''
def comb(sums, result, count):
# 如果成功,就打印;这里成功是指sums为0
if sums < 0:
return
if 0 == sums:
# 这里只有从0到count-1位才是结果
print("满足条件组合")
printResult(result, count)
# 找到结果需要返回
return
# 确定组合中下一个取值的起始范围,确保组合中下一个数字一定不会小于前一个数字
i = 1 if 0 == count else result[count - 1]
print("################ i={i} count={count}".format(i=i, count=count))
# i最多可以取到sums
while i <= sums:
# 设置变量
result[count] = i
count += 1
# 递归
comb(sums - i, result, count)
# 清除变量
count -= 1
# 找下一个数字做为组合中的数字
i += 1
def process():
sums = 4
result = [None for i in range(sums)]
count = 0
result = comb(sums, result, count)
print(result)
if __name__ == "__main__":
process()
如何判断还有几盏灯亮着
题目描述:
感觉思考的很巧妙,服了
100个灯泡排成一排,第一轮将所有灯泡打开,第二轮每隔一个灯泡关掉一个,即排在偶数的灯泡被关掉,第三轮每隔两个灯泡,将开着的灯泡关闭,关闭的灯泡打开, 已从类推, 第100轮结束后, 还有几盏灯灯泡亮着。
分析:
第一轮把所有灯泡打开,第二轮是偶数的关闭,第三轮对三的倍数位置的灯泡操作,第四轮对四的倍数进行操作,最终被操作奇数次的灯泡还是开着的
- 对于每盏灯,当拉动的次数为奇数时, 灯时亮着的, 当拉动的次数时偶数时,灯就是关着的
- 每盏灯的拉动次数与它的编号所含约数的个数有关,它的编号有几个约数,这盏灯就被拉动几次
- 1~100这100个数中有哪几个数,约数的个数是奇数?一个数的约数是成对出现的,只有完全平方根的约数才是奇数个
- 所以题目就变成在1~100个数中,找完全平方根
def factorIsOdd(a):
total = 0
i = 1
while i <= a:
# a 是1到100的数, 下面的if 是看它有几个因数,比如a=1, a//1, a//2, a//3/....一直遍历
if a % i == 0:
# 能被1到100的数整除, +1
total += 1
i += 1
if total % 2 == 1:
# 有奇数个因数就返回1
return 1
else:
return 0
def totalCount(num, n):
count = 0
i = 0
while i < n:
if factorIsOdd(num[i]) == 1:
print("亮着的灯" + str(num[i]))
count += 1
i += 1
return count
if __name__ == "__main__":
# 创建1到100的列表
num = []
for i in range(1, 101):
num.append(i)
count = totalCount(num, 100)
如何组合1, 2, 5 这三个数使其和为100,求共有多少种组合方法
题目描述:
例如100个1, 0个2, 0个5; 50个1, 25个2,0个5。。
分析:
这也是个很巧妙的方法
可以写出方程x+2y+5z=100, 则x+5z=100-2y。 从这个表达式可以看出x+5z是偶数, 且x+5z <= 100。所以问题转化为求x+5z是偶数,且x+5z <= 100 的个数。遍历z可能的取值,来解决。0 <= z <= 20。
- z = 0,x=0,2,4....100 共有100//2 +1 个
- z=1, x=1, 3, 5....95 共95//2 +1 个
- 。。。。。。
def test(n):
count = 0
m = 0
while m <= n:
count += m // 2 + 1
m += 5
return count
print(test(100))
如何用一个随机函数得到另外一个随机函数
题目描述:
有一个func1能返回0和1,返回0,1的概率都为1/2, 怎么利用这个函数得到另一个函数func2,使func2的返回值为0, 1 且返回0的概率为1/4, 1的概率为3/4。
import random
def func1():
return random.randint(0, 1)
def func2():
a1 = func1()
# a1 可能为 0 1
a2 = func1()
# a2 可能为 0 1
tmp = a1
# tmp 可能为 0 1
tmp |= (a2 << 1)
# tmp = tmp | (a2 << 1)
# a2左移一位, 可能00, 10。
# 所以 00, 10 或 00, 01,00|00=00, 00|01=01. 10|00=10,10|01=11, 等于零的概率为四分之一
if tmp == 0:
# 概率为四分之一
return 0
else:
return 1
if __name__ == "__main__":
i = 0
while i < 16:
print(func2())
i += 1
print("\n")
i = 0
while i < 16:
print(func2())
i += 1
如何拿到最多的金币
题目描述:10个房间放着随机数目的金币,每个房间只能进一次,并且只能在一个房间拿金币。一个人采取了如下策略:前4个房间只看不拿,随后房间只要比前4个最多的还多就拿,否则就拿最后一个房间的金币。计算这种概率拿到最多金币的概率。没什么难的
import random
def getMaxNum(n):
if n < 1:
print("参数不合法")
return
# 创建一个有十个随机数的列表
a = []
for i in range(n):
a.append(random.uniform(1, n))
# 找到前四个最大的数
max4 = max(a[:4])
i = 4
while i < n - 1:
# 减1 使不拿最后一个房间的
if a[i] > max4:
return True
i += 1
return False
if __name__ == "__main__":
monitorCount = 1000
success = 0
i = 0
while i < monitorCount:
if getMaxNum(10):
success += 1
i += 1
print(success/monitorCount)
如何求数字的组合
用1, 2, 2, 3, 4, 5这六个数字i,写一个函数, 打印所有不同的排列,例如:512234,412345等, 要求4不能再第三位, 3与5不能相连。 mmp,看了许久,为解其中深意,留给日后机缘巧合再做商榷。
class Test(object):
def __init__(self, arr):
self.numbers = arr
self.visited = [False] * len(self.numbers)
# [False, False, False, False, False, False]
self.graph = [([None] * len(self.numbers)) for i in range(len(self.numbers))]
# [[六个None], [六个None], ...六个]
self.n = 6
self.combination = ''
self.s = set()
def depthFirstSearch(self, start):
# start=0, 1, 2, 3, 4, 5
self.visited[start] = True
# [True, False, False, False, False, False] start=0
# [True, True, False, False, False, False] start=1
self.combination += str(self.numbers[start])
# number = [1, 2, 2, 3, 4, 5]
if len(self.combination) == self.n:
if self.combination.index("4") != 2:
self.s.add(self.combination)
j = 0
while j < self.n:
# graph
# [[0, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1],
# [1, 1, 1, 0, 1, 0], [1, 1, 1, 1, 0, 1], [1, 1, 1, 0, 1, 0]]
# visited [True, False, False, False, False, False] i=0, start=0
if self.graph[start][j] == 1 and self.visited[j] is False:
# j=1 开始符合条件
self.depthFirstSearch(j)
j += 1
self.combination = self.combination[:-1]
self.visited[start] = False
def getAllCombinations(self):
i = 0
while i < self.n:
j = 0
while j < self.n:
if i == j:
self.graph[i][j] = 0
else:
self.graph[i][j] = 1
j += 1
i += 1
# print(self.graph)
# [[0, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1],
# [1, 1, 1, 0, 1, 1], [1, 1, 1, 1, 0, 1], [1, 1, 1, 1, 1, 0]]
self.graph[3][5] = 0
self.graph[5][3] = 0
# print(self.graph)
# [[0, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1],
# [1, 1, 1, 0, 1, 0], [1, 1, 1, 1, 0, 1], [1, 1, 1, 0, 1, 0]]
i = 0
while i < self.n:
self.depthFirstSearch(i)
i += 1
def printAllCombimations(self):
for i in self.s:
print(i)
if __name__ == "__main__":
arr = [1, 2, 2, 3, 4, 5]
t = Test(arr)
t.getAllCombinations()
t.printAllCombimations()