📜  门|门 CS 1999 |第 40 题(1)

📅  最后修改于: 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范围。