cap5 works 1~7

main
lensfrex 5 months ago
parent 14c8770633
commit 63280146bd
Signed by: lensfrex
GPG Key ID: B1E395B3C6CA0356
  1. 3
      .vscode/settings.json
  2. 1
      python/cap5/work1.py
  3. 66
      python/cap5/work2.py
  4. 36
      python/cap5/work3.py
  5. 0
      python/cap5/work4.py
  6. 7
      python/cap5/work5.py
  7. 75
      python/cap5/work6.py
  8. 46
      python/cap5/work7.py

@ -0,0 +1,3 @@
{
"python.analysis.autoImportCompletions": true
}

@ -0,0 +1 @@
# 检验一个给定表达式中的括号是否正确匹配

@ -0,0 +1,66 @@
from fractions import Fraction
# 第五章 作业一
# 有分数1/2,1/3,1/4,1/5,1/6,1/8,1/10,1/12,1/15,求将其中若干个分数相加和恰好等于1的组成方案,并输出
#
# 1. 给定的分数使用 Fraction 类型,可以方便地进行分数的计算和比较。
#
# 2. 使用递归来查找满足条件的组合。参数:
# - `target`:目标和,初始值为 1。
# - `current_combination`:当前已选择的分数组合,初始为空列表。
# - `index`:当前处理的分数在列表中的索引,初始为 0。
#
# 3. 在递归函数中,有两个选择:
# - 不选择当前分数:继续递归,不修改 `target` 和 `current_combination`。
# - 选择当前分数:继续递归,更新 `target` 为 `target - fractions[index]`,并将当前分数添加到 `current_combination` 中。
#
# 4. 当 `target` 等于 0 时,我们找到了一个满足条件的组合,将其打印出来。
#
# 5. 递归继续处理下一个分数,直到遍历完所有分数或找到所有满足条件的组合。
def find_combinations(
target: Fraction,
fractions: list[Fraction],
current_combination: list[Fraction],
index: int,
resultSet: list[list[Fraction]],
):
if target == 0:
resultSet.append(current_combination.copy())
return
if index >= len(fractions):
return
# 不选择当前分数
find_combinations(target, fractions, current_combination, index + 1, resultSet)
# 选择当前分数
find_combinations(
target - fractions[index],
fractions,
current_combination + [fractions[index]],
index + 1,
resultSet,
)
fractions = [
Fraction(1, 2),
Fraction(1, 3),
Fraction(1, 4),
Fraction(1, 5),
Fraction(1, 6),
Fraction(1, 8),
Fraction(1, 10),
Fraction(1, 12),
Fraction(1, 15),
]
result_set = []
find_combinations(
target=1, fractions=fractions, current_combination=[], index=0, resultSet=result_set
)
for result in result_set:
print(" + ".join(map(str, result)) + " = 1")

@ -0,0 +1,36 @@
# 第五章 作业3
# 找出所有由1~9组成的9位数,每个数字只能出现一次,且这个9位数由高位到低位前i位能被i整除
#
# 1. 使用深度优先搜索(DFS)来查找满足条件的 9 位数。
#
# 2. 定义一个 `dfs` 函数,两个参数:
# - `k`:当前已选择的数字个数,初始值为 0。
# - `num`:当前已选择的数字组成的整数,初始值为 0。
#
# 3. 在 `dfs` 函数中,遍历数字 1 到 9。对于每个数字,检查是否已经使用过(通过 `used` 数组判断)。如果没有使用过,我们尝试将该数字添加到当前的数字组合中。
#
# 4. 检查当前数字组合是否满足条件:前 i 位能被 i 整除。如果满足条件,我们继续递归调用 `dfs`,更新 `k` 和 `num`。
#
# 5. 当 `k` 等于 9 时,找到了一个满足条件的 9 位数。
def find(k: int, num: int, used: list[bool], resultSet: list[int]):
if k != 0 and num % k != 0:
return
if k == 9:
resultSet.append(num)
return
# digit: 1 ~ 9
for digit in range(1, 10):
if not used[digit]:
used[digit] = True
find(k + 1, num * 10 + digit, used, resultSet)
# 当前数字撤销使用标记,以便下一个数字的搜索时可用
used[digit] = False
resultSet = []
find(0, 0, [False] * 10, resultSet)
print(resultSet)

@ -0,0 +1,7 @@
# 翻币问题:有N个硬币(N≥10),正面向上排成一排。每次必须翻5个硬币,直到全部反面向上。
def flip_coins(num: int):
pass
result = flip_coins(21)
print(result)

@ -0,0 +1,75 @@
# 等分液体
# 在一个瓶子中装有8(一般情形下为偶数N)升汽油,要平均分成两份,
# 但只有一个装3(一般情形下为N/2-1)升和装5(一般情形下为N/2+1)升的量杯(都没有刻度)。
# 若有解,则打印出所有把汽油分成两等分的操作过程。若无解,则打印“No”。
from collections import deque
def pour(source, target, target_capacity):
amount = min(source, target_capacity - target)
return source - amount, target + amount
def get_next_states(state, capacities):
next_states = []
bottle, cup3, cup5 = state
max_bottle, max_cup3, max_cup5 = capacities
# bottle -> cup3
next_states.append(pour(bottle, cup3, max_cup3) + (cup5,))
# bottle -> cup5
next_states.append(pour(bottle, cup5, max_cup5) + (cup3,))
# cup3 -> bottle
next_states.append(
(pour(cup3, bottle, max_bottle)[1],) + pour(cup3, bottle, max_bottle)
)
# cup5 -> bottle
next_states.append(
(pour(cup5, bottle, max_bottle)[1], cup3, pour(cup5, bottle, max_bottle)[0])
)
# cup3 -> cup5
next_states.append((bottle,) + pour(cup3, cup5, max_cup5))
# cup5 -> cup3
next_states.append((bottle,) + pour(cup5, cup3, max_cup3)[::-1])
return next_states
def bfs(initial_state, capacities, target):
queue = deque([(initial_state, [])])
visited = set()
while queue:
(state, path) = queue.popleft()
if (state[0] == target and state[1] == target) or (
state[0] == target and state[2] == target
):
return path
if state in visited:
continue
visited.add(state)
for next_state in get_next_states(state, capacities):
if next_state not in visited:
queue.append((next_state, path + [next_state]))
return "No"
N = 8
capacities = (N, N // 2 - 1, N // 2 + 1)
initial_state = (N, 0, 0)
target = N // 2
result = bfs(initial_state, capacities, target)
if result == "No":
print("No")
else:
print("状态步骤:(汽油瓶, 5L杯, 3L杯)")
for step in result:
print(step)

@ -0,0 +1,46 @@
# 一个正整数有可能可以被表示为n(n≥2)个连续的正整数之和,如n=15时,
# 15=1+2+3+4+5
# 15=4+5+6
# 15=7+8
# 请编写算法,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。
# 需要找到所有可能的连续正整数序列,这些序列的和等于给定的正整数 N 。
# 考虑到一个连续的正整数序列 a, a+1, a+2, ..., a+(k-1) ,和可以表示为:
#
# S = a + (a + 1) + (a + 2) + ... + (a + k - 1)
#
# 简化为:
#
# S = k * a + (k*(k - 1)) / 2
#
# S 是给定的正整数 N,a 是序列的起始数,k 是序列中的项数。
#
# 所以有:
#
# N = k * a + (k*(k - 1)) / 2
#
# 即:
#
# 2N = k * (2a + k - 1)
#
# 为了找到所有满足条件的序列,从 2 开始遍历可能的 k 值,直到 k*(k-1) < 2N为止,检查是否有整数 a 使得上面的等式成立。
def find_consecutive_sequences(N):
result = []
k = 2
while k * (k - 1) < 2 * N:
if (2 * N - k * (k - 1)) % (2 * k) == 0:
a = (2 * N - k * (k - 1)) // (2 * k)
sequence = [a + i for i in range(k)]
result.append(sequence)
k += 1
return result
N = 15
sequences = find_consecutive_sequences(N)
for seq in sequences:
print(seq)
Loading…
Cancel
Save