You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以最少rand()调用为100×100零矩阵随机填充100个1?

解决方案:用一维映射+Fisher-Yates变种实现无重复随机选择

当然可以做到!而且这个思路能通用到任意m×n的二维矩阵场景,刚好只需要100次rand()调用就完成填充,完全不会出现重复选位置的问题。

核心思路:二维坐标转一维索引 + 动态缩小可选范围

我们可以把二维矩阵的所有位置映射成连续的一维整数,然后用不需要完整洗牌的Fisher-Yates算法变种,每次从剩余未选的位置里随机挑一个,选完后就把该位置从可选池里移除——全程不需要检查位置是否已被填充,也不会重复调用rand()。

具体步骤(针对100×100矩阵)

  1. 二维转一维映射:把矩阵的每个位置(x,y)转换成一个唯一的一维索引,公式为:

    idx = x * 100 + y  // 行优先,x是行号,y是列号
    

    这样整个100×100矩阵就对应0到9999的连续整数(共10000个位置)。

  2. 动态随机选择:

    • 初始时,可选位置总数total = 100*100 = 10000
    • 循环100次(刚好对应要填充的100个1):
      • 调用rand()生成一个0到total-1之间的随机数r
      • 把r转回到二维坐标:x = r // 100,y = r % 100
      • 将M[x][y]设为1
      • 把total减1——这一步相当于把刚选的位置从可选池里移除,下次rand()的范围自动缩小,不会再选到已标记的位置

伪代码示例

// 初始化100×100矩阵全为0
int M[100][100] = {0};
int total_positions = 100 * 100;
int target_count = 100;

for (int i = 0; i < target_count; i++) {
    // 生成当前剩余可选位置中的随机索引
    int rand_idx = rand() % total_positions;
    // 转换为二维坐标
    int x = rand_idx / 100;
    int y = rand_idx % 100;
    // 标记为1
    M[x][y] = 1;
    // 可选位置总数减1,排除已选位置
    total_positions--;
}

通用化到任意二维矩阵

不管你的矩阵是m行n列,要选择k个不重复的随机位置(k ≤ m×n),只需要调整几个参数:

  • 总可选位置数total = m * n
  • 二维转一维的公式:idx = x * n + y(行优先),或者idx = y * m + x(列优先,根据你的需求选择)
  • 转回到二维坐标:x = idx // n,y = idx % n(对应行优先的映射)

为什么这个方法能保证100次rand()调用?

每次循环只调用一次rand(),刚好循环100次就完成所有填充。而且因为每次选完后都会缩小可选范围,相当于从剩余的未选位置里随机挑选,完全不会出现重复选中已填充位置的情况,也就不需要额外调用rand()来重试。

内容的提问来源于stack exchange,提问作者Sazzad Hissain Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:12:42