网易首页 > 网易号 > 正文 申请入驻

2026-07-15:恰好看到 K 个人的方向选择。用go语言,有 n 个人站成一排,编号依次为 0 到 n-1。每个人都必须独立地选定一个朝向:要么朝

0
分享至

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。

一、题意拆解 1. 人群划分

总共有n个人,下标0 ~ n-1,目标人物在pos位置,整排被分成三段独立人群:

  1. 1.左区L:编号< pos,总人数left = pos

  2. 2.目标人P:编号pos,1个人

  3. 3.右区R:编号> pos,总人数right = n - pos - 1

2. 可见规则(核心判定条件)

设目标人P能看到的总人数 = 左侧可见人数 + 右侧可见人数,要求总和恰好等于k

  1. 1. 左侧任意一人(左区):只有朝左L,P才能看见他;朝右R则看不见。

  2. 2. 右侧任意一人(右区):只有朝右R,P才能看见他;朝左L则看不见。

  3. 3. 目标人P自己朝左/朝右完全不影响可见计数,两种朝向都合法,固定贡献乘以系数2。

3. 拆分数学方程

设:

  • • 从左区left人中选出x个人朝左(被P看见),剩余left - x人朝右(看不见)

  • • 从右区right人中选出y个人朝右(被P看见),剩余right - y人朝左(看不见)
    约束条件:x + y = k,其中0 ≤ x ≤ left0 ≤ y ≤ right

总方案 = 所有满足x+y=k的组合方案之和 × 目标人自身2种朝向。
对一组合法x,y的局部方案计算:

  1. 1. 左区选x人可见:组合数C(left, x);剩下人强制不可见,朝向唯一确定,无额外乘法。

  2. 2. 右区选y人可见:组合数C(right, y);剩下人强制不可见,朝向唯一确定,无额外乘法。

  3. 3. 单组贡献:C(left, x) × C(right, y)

  4. 4. 全部合法x累加总和:sum_{x} C(left, x) × C(right, k-x)(x范围保证y合法)

  5. 5. 最终答案 = 累加总和 × 2 再对 1e9+7 取模。

样例验证(n=3, pos=1, k=0)
  • • left = pos = 1(下标0),right = 3-1-1 = 1(下标2)

  • • k=0,要求x+y=0,只能 x=0,y=0

    • • C(1,0)=1:左边1个人全部不可见,必须朝右,仅1种方案

    • • C(1,0)=1:右边1个人全部不可见,必须朝左,仅1种方案

  • • 累加和 = 1×1 = 1

  • • 目标人两种朝向:1 × 2 = 2,和样例输出一致。

二、预处理阶乘与逆元组合数完整流程(分步详解)

题目n上限1e5,多次查询组合数,采用阶乘+阶乘逆元O(n)预处理,O(1)单次求组合数,分两大阶段:预处理阶段 + 计算答案阶段。

阶段1:全局预处理(init函数执行,程序启动只跑一次)

模数mod = 1e9+7,最大预处理长度mx = 100001覆盖n上限1e5。

步骤1:预处理阶乘数组 fac[]

fac[i]存储i! mod mod

  1. 1. 初始化边界:0的阶乘fac[0] = 1

  2. 2. 循环i从1到mx-1:
    fac[i] = fac[i-1] × i % mod
    递推算出 1!,2!,3!...100000!,全部取模防止溢出。

步骤2:预处理阶乘逆元数组 invF[]

模意义下,阶乘逆元满足invF[i] = (i!)^{-1} mod mod,使用费马小定理:质数mod下a^{-1}=a^{mod-2} mod mod

  1. 1. 先求最大阶乘的逆元:invF[mx-1] = pow(fac[mx-1], mod-2)
    pow函数是快速幂,二分幂次快速计算高次取模。

  2. 2. 逆推递推所有逆元:i从mx-1倒推到1
    公式推导:
    (i-1)!^{-1} = i × (i!)^{-1} mod mod
    invF[i-1] = invF[i] × i % mod
    从最大数往回算,不用重复快速幂,线性时间完成全部逆元。

步骤3:快速幂pow函数原理(预处理依赖)

输入底数x、指数n,返回x^n mod mod

  1. 1. 结果res初始为1

  2. 2. 循环分解指数n二进制:每次n整除2

  • • 当前二进制最低位为1:res = res × x % mod,累积当前底数

  • • 底数平方取模:x = x × x % mod

3. 循环结束返回res,时间O(logn)。

阶段2:组合数查询函数 comb(n,m) O(1) 单次调用

输入总人数n、选取m人,返回*****) mod mod:

  1. 1. 边界判断:m<0 或 m>n,不存在合法组合,直接返回0

  2. 2. 合法情况公式:

    模除法转乘法逆元:
    comb = fac[n] × invF[m] % mod × invF[n-m] % mod

阶段3:主逻辑 countVisiblePeople 计算答案(原题核心逻辑)

入参n,pos,k:

  1. 1. 计算左区人数 left = pos;右区人数 right = n-pos-1

  2. 2. 枚举所有合法x(左侧可见人数):
    x的合法区间:x ≥ 0,y=k-x ≥ 0,x ≤ left,y ≤ right
    max(0, k-right) ≤ x ≤ min(left, k)
    对每个x,y=k-x,累加comb(left, x) * comb(right, y) mod mod,得到总基础方案和sum

  3. 3. 目标人pos有朝左、朝右2种朝向,答案 = sum × 2 % mod

阶段4:main函数流程
  1. 1. 给定输入n,pos,k

  2. 2. 调用countVisiblePeople计算总方案数

  3. 3. 打印输出结果

三、时间复杂度完整分布 1. 预处理 init 总时间 O(mx) = O(1e5)
  1. 1. 阶乘数组循环:O(mx),mx=1e5+1

  2. 2. 快速幂计算最大逆元:O(log mod) ≈ O(30),常数可忽略

  3. 3. 逆元倒推循环:O(mx)
    预处理整体线性O(1e5),程序启动仅执行1次。

2. 单次查询计算 countVisiblePeople 时间
  1. 1. 枚举合法x求和:枚举次数最多不超过 min(left, k)+1,最坏极端情况O(n);
    但n上限1e5,单次查询最多1e5次循环,每次循环两次O(1) comb调用。

  2. 2. comb函数单次O(1),仅三次乘法取模。

  3. 3. 快速幂仅预处理阶段使用,查询阶段无log开销。

3. 全局总时间复杂度总结
  • • 预处理:O(1e5)

  • • 单次询问:最坏 O(n)
    若只运行一组输入(main单组测试),整体时间复杂度:O(1e5 + n),n≤1e5,等价O(1e5)。

四、额外空间复杂度分布

全局开辟两个定长数组,无动态内存:

  1. 1. fac数组:长度 mx=100001,存储int,空间 O(mx)

  2. 2. invF数组:长度 mx=100001,存储int,空间 O(mx)
    其余变量(循环i、临时乘积、n/pos/k/left/right/sum等)均为单个int常数空间 O(1)。

总额外空间复杂度:O(mx) = O(1e5)。

Go完整代码如下:

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)
}

Python完整代码如下:

# -*-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()

C++完整代码如下:

  

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助力您的未来发展。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
防空导弹严重短缺,泽连斯基公开喊话,乌克兰失去导弹拦截能力?

防空导弹严重短缺,泽连斯基公开喊话,乌克兰失去导弹拦截能力?

环球网资讯
2026-08-07 06:48:17
“富人区的小学生,这样很正常”,深圳俩男孩吃饭视频,让大人自愧不如

“富人区的小学生,这样很正常”,深圳俩男孩吃饭视频,让大人自愧不如

泽泽先生
2026-08-07 12:46:16
你的身体自带顶级自愈系统,90%的人一辈子都没真正启动过

你的身体自带顶级自愈系统,90%的人一辈子都没真正启动过

青苹果sht
2026-08-01 05:11:32
瓦尔塔破产:一家德国电池公司的旧优势,如何被中国制造体系改写

瓦尔塔破产:一家德国电池公司的旧优势,如何被中国制造体系改写

阿纂看事
2026-08-05 15:50:58
A股:今天收在3940了,下周一,股市行情提前分析!

A股:今天收在3940了,下周一,股市行情提前分析!

明心
2026-08-07 15:44:00
欧盟砍向贸易这一刀,竟砍出了工人的福音吗?

欧盟砍向贸易这一刀,竟砍出了工人的福音吗?

寰球经纬所
2026-08-06 21:19:32
员工用代码17小时删光公司89TB数据:只为腾出存储空间接私活

员工用代码17小时删光公司89TB数据:只为腾出存储空间接私活

快科技
2026-08-05 14:26:20
台风“白海豚”体型变大!环流面积接近13个浙江那么大

台风“白海豚”体型变大!环流面积接近13个浙江那么大

上游新闻
2026-08-07 10:27:04
半月内两起儿童基因编辑试验死亡事件曝光,业内警示:追求“全球首创”不能忽视临床安全与合规要求

半月内两起儿童基因编辑试验死亡事件曝光,业内警示:追求“全球首创”不能忽视临床安全与合规要求

每日经济新闻
2026-08-07 11:59:04
演员终将被AI取代?41岁戚薇闯入AI漫剧赛道,杜华的话得到了印证

演员终将被AI取代?41岁戚薇闯入AI漫剧赛道,杜华的话得到了印证

娱说瑜悦
2026-08-07 16:18:54
上海前首富周正毅近照曝光!穿满身奢品挤地铁,整个人看起来憔悴

上海前首富周正毅近照曝光!穿满身奢品挤地铁,整个人看起来憔悴

小徐讲八卦
2026-08-07 15:48:41
王室贵族圈的纨绔子弟能玩到什么程度?

王室贵族圈的纨绔子弟能玩到什么程度?

欧洲王室八卦
2026-08-07 23:12:07
中央考核巡查组向多地反馈情况,都提到同一问题

中央考核巡查组向多地反馈情况,都提到同一问题

上观新闻
2026-08-07 20:59:40
涉嫌严重违纪违法,张玲被查!

涉嫌严重违纪违法,张玲被查!

阜阳发布
2026-08-07 15:15:39
队史标王!皇马官宣19岁迪奥曼德加盟:转会费1.4亿欧+签7年 夏窗第6人

队史标王!皇马官宣19岁迪奥曼德加盟:转会费1.4亿欧+签7年 夏窗第6人

风过乡
2026-08-06 22:29:24
李小璐首次公开与贾乃亮真实离婚时间:实锤自己婚姻出轨的同时,也揭露了一个婚姻里的扎心真相

李小璐首次公开与贾乃亮真实离婚时间:实锤自己婚姻出轨的同时,也揭露了一个婚姻里的扎心真相

不执的小世界
2026-08-05 15:44:25
燃油车时代会很快结束?内行人预测:油价很可能是最后的关键!

燃油车时代会很快结束?内行人预测:油价很可能是最后的关键!

离离言几许
2026-08-07 16:09:59
汪峰阻止14岁女儿买大牌,“孩子应该知道父母的不易”,称自己买衣服80%都在淘宝

汪峰阻止14岁女儿买大牌,“孩子应该知道父母的不易”,称自己买衣服80%都在淘宝

极目新闻
2026-08-07 11:55:28
大快人心!婚外胚胎销毁后,政协委员给原配支大招,男方要慌了

大快人心!婚外胚胎销毁后,政协委员给原配支大招,男方要慌了

小鋭有话说
2026-08-07 00:18:04
情况突然不对劲,伊朗最高领袖的亲戚,打算纠集25万人发动政变?

情况突然不对劲,伊朗最高领袖的亲戚,打算纠集25万人发动政变?

临云史策
2026-08-07 21:45:51
2026-08-08 00:27:00
moonfdd incentive-icons
moonfdd
福大大架构师每日一题
1378文章数 78关注度
往期回顾 全部

科技要闻

突然涨价,"只收电费钱"的梁文锋,变了吗

头条要闻

穆杰塔巴被指给总统下"最后警告" 爆料人发声意味深长

头条要闻

穆杰塔巴被指给总统下"最后警告" 爆料人发声意味深长

体育要闻

去年信誓旦旦3000万 今年NBA查无此人

娱乐要闻

周也热恋结束,六个字暴露单身状态

财经要闻

腾讯WorkBuddy领跑AI办公 阿里字节急了?

汽车要闻

越7全球首秀 传祺开始进攻方盒子越野

态度原创

家居
教育
时尚
手机
数码

家居要闻

2026建博会(广州) 公装联探展交流活动

教育要闻

英国本土学生含量最高的几所英国大学!

工装,好穿又有质感!

手机要闻

消息称苹果正在测试iOS 26.6.1系统

数码要闻

苹果旗舰台式机Mac Pro迎来20周年纪念 淘汰停产已有五个月

无障碍浏览 进入关怀版