📅  最后修改于: 2023-12-03 14:58:35.423000             🧑  作者: Mango
本题为《门》题目第40题,题目编号为CS1999。该题目难度为普及/提高-。
有一个门厅,你可以在门厅中摆放箱子。 门厅一共有 n 个位置供你放置箱子,编号为 1∼n。每个位置最多只能放置一个箱子,且必须放满 n 个位置。 你有 m 个箱子,每个箱子占据一个位置。箱子的尺寸不同,但是任意两个箱子放到门厅中后都可以互相转换位置。 你要将这 m 个箱子放到门厅中,使得这 m 个箱子不与门口相邻。即对于任意 1≤i≤m,都有恰好一个箱子被放在第 xi 个位置,且相邻两个箱子不能都被放在门口。
共一行,包含两个整数 n 和 m,表示门厅位置数量和箱子数量。
共一行,包含一个整数,表示所有合法方案数,由于答案可能很大,请输出对 10^9+7 取模后的结果。
1≤n≤10^6,1≤m≤min(n−2,10^5)
5 3
6
此题可以采用排列组合的思想,先将门厅和箱子的位置排列,即门口与箱子的位置进行排列组合,再将箱子放置在门厅上,就可以得到每一种不与门口相邻的方案,最后统计方案总数。
此处需要注意,门厅和箱子的位置排列组合的数目需要提前计算,否则会超出时间限制。
以下为该题的AC代码:
def fact(n):
res = 1
for i in range(2, n+1):
res *= i
return res
n, m = map(int, input().split())
if m == 1:
print(str(n-2))
else:
mod = 10**9 + 7
k = n - m - 1
dev = fact(n-m)
for i in range(k):
dev = (dev * (n-m-i)) % mod
print(dev)
在排列组合问题中,常常需要进行求组合数或者求排列数的操作,此时需要使用到阶乘,可自定义阶乘函数,或使用math库中的阶乘函数。同时,在计算时可能会用到取模操作,注意取模后的数值不要超出int范围。