
2026-07-15:恰好看到 K 个人的方向选择。用go语言,有 n 个人站成一排,编号依次为 0 到 n-1。每个人都必须独立地选定一个朝向:要么朝左,要么朝右。如果一个人朝左,那么他只能被站在他右边的人看到;如果朝右,那么他只能被站在他左边的人看到。
现在,我们关注站在位置 pos 的那个人。对于站在他左边的每一个人(即编号小于 pos 的人),只有当那个人朝左时,他才能看到。对于站在他右边的每一个人(即编号大于 pos 的人),只有当那个人朝右时,他才能看到。
请你计算一共有多少种为所有人分配朝向的方案,能使得位于 pos 的人恰好看到 k 个人。由于答案可能很大,请将结果对 1000000007 取模后返回。
1 <= n <= 100000。
0 <= pos, k <= n - 1。
输入: n = 3, pos = 1, k = 0。
输出: 2。
解释:
下标 0 在 pos = 1 的左侧,下标 2 在 pos = 1 的右侧。
为了看到 k = 0 个人,下标 0 必须选择 'R',且下标 2 必须选择 'L',这样两人都不可见。
位于下标 1 的人可以选择 'L' 或 'R',因为这不会影响计数。因此,答案是 2。
题目来自力扣3881。
总共有 n 个人,下标 0 ~ n-1,目标人物在 pos 位置,整排被分成三段独立人群:
< pos,总人数 left = pos 人pos,1个人> pos,总人数 right = n - pos - 1 人设目标人P能看到的总人数 = 左侧可见人数 + 右侧可见人数,要求总和恰好等于 k:
设:
left 人中选出 x 个人朝左(被P看见),剩余 left - x 人朝右(看不见)right 人中选出 y 个人朝右(被P看见),剩余 right - y 人朝左(看不见)
约束条件:x + y = k,其中 0 ≤ x ≤ left、0 ≤ y ≤ right。总方案 = 所有满足 x+y=k 的组合方案之和 × 目标人自身2种朝向。
对一组合法 x,y 的局部方案计算:
C(left, x);剩下人强制不可见,朝向唯一确定,无额外乘法。C(right, y);剩下人强制不可见,朝向唯一确定,无额外乘法。C(left, x) × C(right, y)sum_{x} C(left, x) × C(right, k-x)(x范围保证y合法)x+y=0,只能 x=0,y=0题目n上限1e5,多次查询组合数,采用阶乘+阶乘逆元O(n)预处理,O(1)单次求组合数,分两大阶段:预处理阶段 + 计算答案阶段。
模数 mod = 1e9+7,最大预处理长度 mx = 100001 覆盖n上限1e5。
fac[i] 存储 i! mod mod
fac[0] = 1fac[i] = fac[i-1] × i % mod
递推算出 1!,2!,3!...100000!,全部取模防止溢出。模意义下,阶乘逆元满足 invF[i] = (i!)^{-1} mod mod,使用费马小定理:质数mod下 a^{-1}=a^{mod-2} mod mod。
invF[mx-1] = pow(fac[mx-1], mod-2)
pow函数是快速幂,二分幂次快速计算高次取模。(i-1)!^{-1} = i × (i!)^{-1} mod mod
即 invF[i-1] = invF[i] × i % mod
从最大数往回算,不用重复快速幂,线性时间完成全部逆元。输入底数x、指数n,返回 x^n mod mod:
输入总人数n、选取m人,返回*****) mod mod:
comb = fac[n] × invF[m] % mod × invF[n-m] % mod入参n,pos,k:
max(0, k-right) ≤ x ≤ min(left, k)
对每个x,y=k-x,累加 comb(left, x) * comb(right, y) mod mod,得到总基础方案和sum全局开辟两个定长数组,无动态内存:
总额外空间复杂度:O(mx) = O(1e5)。
.
package main
import (
"fmt"
)
const mod = 1_000_000_007
const mx = 100_001
var fac [mx]int// fac[i] = i!
var invF [mx]int// invF[i] = i!^-1 = pow(i!, mod-2)
func init() {
fac[0] = 1
for i := 1; i < mx; i++ {
fac[i] = fac[i-1] * i % mod
}
invF[mx-1] = pow(fac[mx-1], mod-2)
for i := mx - 1; i > 0; i-- {
invF[i-1] = invF[i] * i % mod
}
}
func pow(x, n int)int {
res := 1
for ; n > 0; n /= 2 {
if n%2 > 0 {
res = res * x % mod
}
x = x * x % mod
}
return res
}
// 从 n 个数中选 m 个数的方案数
func comb(n, m int)int {
if m < 0 || m > n {
return0
}
return fac[n] * invF[m] % mod * invF[n-m] % mod
}
func countVisiblePeople(n, _, k int)int {
return comb(n-1, k) * 2 % mod
}
func main() {
n := 3
pos := 1
k := 0
result := countVisiblePeople(n, pos, k)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
MOD = 1_000_000_007
MX = 100_001
# 预计算阶乘和逆阶乘
fac = [1] * MX
invF = [1] * MX
fac[0] = 1
for i in range(1, MX):
fac[i] = fac[i-1] * i % MOD
invF[MX-1] = pow(fac[MX-1], MOD-2, MOD) # 内置快速幂支持取模
for i in range(MX-1, 0, -1):
invF[i-1] = invF[i] * i % MOD
def comb(n: int, m: int) -> int:
"""从 n 个数中选 m 个数的方案数(模 MOD)"""
if m < 0 or m > n:
return0
return fac[n] * invF[m] % MOD * invF[n-m] % MOD
def countVisiblePeople(n: int, pos: int, k: int) -> int:
return comb(n-1, k) * 2 % MOD
def main():
n = 3
pos = 1
k = 0
result = countVisiblePeople(n, pos, k)
print(result)
if __name__ == "__main__":
main()
.
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1'000'000'007LL;
const int MX = 100'001;
long long fac[MX]; // fac[i] = i!
long long invF[MX]; // invF[i] = (i!)^(-1) mod MOD
// 快速幂取模
long long modpow(long long a, long long e) {
long long res = 1;
while (e > 0) {
if (e & 1) res = res * a % MOD;
a = a * a % MOD;
e >>= 1;
}
return res;
}
// 初始化阶乘和逆阶乘(对应 Go 的 init 函数)
void init() {
fac[0] = 1;
for (int i = 1; i < MX; i++) {
fac[i] = fac[i - 1] * i % MOD;
}
invF[MX - 1] = modpow(fac[MX - 1], MOD - 2);
for (int i = MX - 1; i > 0; i--) {
invF[i - 1] = invF[i] * i % MOD;
}
}
// 组合数 C(n, m) 模 MOD
long long comb(int n, int m) {
if (m < 0 || m > n) return0;
return fac[n] * invF[m] % MOD * invF[n - m] % MOD;
}
// 原 countVisiblePeople,pos 参数未使用(用注释忽略)
long long countVisiblePeople(int n, int/*pos*/, int k) {
return comb(n - 1, k) * 2 % MOD;
}
int main() {
init(); // 必须显式调用初始化
int n = 3;
int pos = 1;
int k = 0;
long long result = countVisiblePeople(n, pos, k);
cout << result << '\n';
return0;
}

·
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,让AI助力您的未来发展。