【问题标题】:Very interesting program of building pyramid非常有趣的金字塔建造程序
【发布时间】:2011-06-24 19:36:49
【问题描述】:

我遇到了这个在金字塔中打印数字的非常有趣的程序。

如果 n = 1 则打印以下内容,

1  2
4  3

如果 n = 2 则打印以下内容,

1  2  3
8  9  4
7  6  5

如果 n = 3 则打印以下内容,

1   2   3   4
12  13  14  5
11  16  15  6
10   9   8  7

我可以使用相当多的循环和变量来打印所有这些,但它看起来非常具体。您可能已经注意到,所有这些金字塔填充都从一个方向开始,直到找到填充的路径。您可能已经注意到 1,2,3,4,5,6,7,8,9,10,11,12 在外边缘归档,直到找到 1 所以在 12 之后进入第二行并打印 13,14等等。它以螺旋模式打印,就像蛇游戏一样,蛇会一直走下去,直到撞到自己为止。

我想知道这个金字塔生成背后是否有任何算法,或者它只是棘手的耗时金字塔生成程序。

提前致谢。这是一个非常有趣的具有挑战性的计划,所以我恳请您不需要投票管道:)

【问题讨论】:

  • 我会说spiral而不是pyramid
  • 我在逻辑上同意它的螺旋,但在物理上同意它的金字塔
  • 这种模式称为Spiral Matrix(请参阅链接了解 41 种语言的解决方案)。

标签: algorithm spiral


【解决方案1】:

我为你的问题做了一个小的递归算法。

public int Determine(int n, int x, int y)
{
  if (y == 0) return x + 1;         // Top
  if (x == n) return n + y + 1;     // Right
  if (y == n) return 3 * n - x + 1; // Bottom
  if (x == 0) return 4 * n - y + 1; // Left
  return 4 * n + Determine(n - 2, x - 1, y - 1);
}

您可以使用双 for 循环来调用它。 x 和 y 从 0 开始:

for (int y=0; y<=n; y++) 
  for (int x=0; x<=n; x++) 
    result[x,y] = Determine(n,x,y);

【讨论】:

  • @C.Zonnerberg -- 我发现这很有趣,只是为了好玩,我决定在 C 中尝试一下。我必须对上述算法进行一些更改才能获得所需的输出。我在大多数地方交换了 x 和 y,并将几个 n 更改为 n-1。 (我将发布 C 代码及其输出作为答案)
  • 是的,绝对是经典的一对一:您需要将您的 n 转换为 n-1,因为计数从 0 开始。除此之外,+1。
  • 我希望我能为这个解决方案再奖励一个 +1,因为我发现它比 Rosetta Code 的大多数解决方案更优雅。
【解决方案2】:

这是实现@C.Zonnerberg 提交的基本算法的一些 C 代码,我的示例使用 n=6 处理 6x6 数组。

我必须进行一些更改才能获得我期望的输出方式。我交换了大部分 x'sy's 并将几个 n's 更改为 n-1 并将 for 循环中的比较从 &lt;= 更改为 &lt;

int main(){
  int x,y,n;
  int result[6][6];
  n=6;
  for (x=0; x<n; x++){
    for (y=0; y<n; y++) {
      result[x][y] = Determine(n,x,y);
      if(y==0)
        printf("\n[%d,%d] = %2d, ", x,y, result[x][y]);
      else
        printf("[%d,%d] = %2d, ", x,y, result[x][y]);
    }
  }
return 0;
}

int Determine(int n, int x, int y)
{
  if (x == 0) return y + 1;         // Top
  if (y == n-1) return n + x;     // Right
  if (x == n-1) return 3 * (n-1) - y + 1; // Bottom
  if (y == 0) return 4 * (n-1) - x + 1; // Left
  return 4 * (n-1) + Determine(n - 2, x - 1, y- 1);
}

输出

[0,0] =  1, [0,1] =  2, [0,2] =  3, [0,3] =  4, [0,4] =  5, [0,5] =  6,
[1,0] = 20, [1,1] = 21, [1,2] = 22, [1,3] = 23, [1,4] = 24, [1,5] =  7,
[2,0] = 19, [2,1] = 32, [2,2] = 33, [2,3] = 34, [2,4] = 25, [2,5] =  8,
[3,0] = 18, [3,1] = 31, [3,2] = 36, [3,3] = 35, [3,4] = 26, [3,5] =  9,
[4,0] = 17, [4,1] = 30, [4,2] = 29, [4,3] = 28, [4,4] = 27, [4,5] = 10,
[5,0] = 16, [5,1] = 15, [5,2] = 14, [5,3] = 13, [5,4] = 12, [5,5] = 11,

【讨论】:

    【解决方案3】:

    对于全零数组,您可以从 [row,col] = [0,0] 开始,填充此空间,然后将 [0,1] 添加到位置(向右一个),直到它位于结束或运行到非零。

    然后向下(添加 [1,0]),填充空间直到它结束或运行到非零。

    然后向左走(添加 [0,-1]),填充空格直到它结束或遇到非零。

    然后向上(添加 [-1,0]),填充空间直到它结束或运行到非零。

    然后重复...

    【讨论】:

      猜你喜欢
      • 2021-07-08
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      • 2014-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多