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

如何在1-80数字矩阵中生成不重叠的x组y个块状数字(Delphi)

Delphi实现8x10矩阵生成不重叠2x2数字块方案(x=2,y=4)

核心逻辑梳理

1. 数字与矩阵坐标映射

针对1-80的8行10列矩阵,采用0-based坐标(行r:0~7,列c:0~9)实现双向转换:

  • 数字转坐标:r := (n - 1) div 10; c := (n - 1) mod 10;
  • 坐标转数字:n := r * 10 + c + 1;

2. 2x2块的有效范围

2x2块的起始坐标(r,c)必须满足:

  • 行方向:r + 1 < 8 → r ∈ 0~6
  • 列方向:c + 1 < 10 → c ∈ 0~8
    总计7×9=63个有效2x2块,每个块包含的4个数字对应坐标:(r,c)、(r,c+1)、(r+1,c)、(r+1,c+1)。

3. 块重叠判断规则

两个块A(rA,cA)和B(rB,cB)不重叠的条件是:行范围无交集 或 列范围无交集,代码逻辑:

function IsBlocksNonOverlap(const A, B: TBlock): Boolean;
begin
  Result := (A.r + 1 < B.r) or (B.r + 1 < A.r) or (A.c + 1 < B.c) or (B.c + 1 < A.c);
end;

高效编码实现

1. 定义数据结构

type
  TBlock = record
    r, c: Integer;          // 2x2块的起始坐标(0-based)
    Numbers: array[0..3] of Integer; // 块包含的4个数字
  end;

2. 生成单个有效2x2块

function GenerateSingleBlock: TBlock;
var
  r, c: Integer;
begin
  // 随机生成有效起始坐标
  r := Random(7);
  c := Random(9);
  // 填充块内数字
  Result.r := r;
  Result.c := c;
  Result.Numbers[0] := r * 10 + c + 1;
  Result.Numbers[1] := r * 10 + (c + 1) + 1;
  Result.Numbers[2] := (r + 1) * 10 + c + 1;
  Result.Numbers[3] := (r + 1) * 10 + (c + 1) + 1;
end;

3. 生成x个不重叠块(以x=2为例)

function GenerateNonOverlapBlocks(const Count: Integer): TArray<TBlock>;
var
  i, j: Integer;
  CurrentBlock: TBlock;
  IsValid: Boolean;
begin
  SetLength(Result, Count);
  // 生成第一个块
  Result[0] := GenerateSingleBlock;
  // 生成后续块,确保与已有块不重叠
  for i := 1 to Count - 1 do
  begin
    repeat
      CurrentBlock := GenerateSingleBlock;
      IsValid := True;
      for j := 0 to i - 1 do
      begin
        if not IsBlocksNonOverlap(Result[j], CurrentBlock) then
        begin
          IsValid := False;
          Break;
        end;
      end;
    until IsValid;
    Result[i] := CurrentBlock;
  end;
end;

4. 使用示例

procedure TForm1.Button1Click(Sender: TObject);
var
  Blocks: TArray<TBlock>;
  i: Integer;
begin
  Randomize;
  Blocks := GenerateNonOverlapBlocks(2);
  // 输出结果到Memo
  for i := 0 to High(Blocks) do
  begin
    Memo1.Lines.Add(Format('第%d组数字: %d, %d, %d, %d', 
      [i+1, Blocks[i].Numbers[0], Blocks[i].Numbers[1], Blocks[i].Numbers[2], Blocks[i].Numbers[3]]));
  end;
end;

优化方案(针对大x场景)

当需要生成的组数较多时,可预先生成所有有效块列表,每次选块后从列表中移除所有重叠的块,后续直接从剩余列表随机选择,避免重复判断。也可采用位掩码记录已占用数字,提升重叠判断效率:

type
  TBitMask = array[0..1] of UInt64; // 前64位存1-64,后16位存65-80

function IsBlockAvailable(const Mask: TBitMask; const Block: TBlock): Boolean;
var
  n, idx, bit: Integer;
begin
  Result := True;
  for n in Block.Numbers do
  begin
    idx := (n - 1) div 64;
    bit := (n - 1) mod 64;
    if (Mask[idx] and (1 shl bit)) <> 0 then
    begin
      Result := False;
      Break;
    end;
  end;
end;

内容的提问来源于stack exchange,提问作者Daniel Hobson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:43:11