如何从给定数字制作金字塔? [关闭]

问题描述 投票:0回答:2

我试图用给定数量的恒星制作一个倒金字塔。

当我们知道行数时,任何人都可以绘制倒金字塔。

我们可以像这样制作倒金字塔

#include <stdio.h>
int main()
{
    int i, space, rows, k=0, count = 0, count1 = 0;

    printf("Enter number of rows: ");
    scanf("%d",&rows);

    for(i=1; i<=rows; ++i)
    {
        for(space=1; space <= rows-i; ++space)
        {
            printf("  ");
            ++count;
        }
        while(k != 2*i-1)
        {
            if (count <= rows-1)
            {
                printf("%d ", i+k);
                ++count;
            }
            else
            {
                ++count1;
                printf("%d ", (i+k-2*count1));
            }
            ++k;
        }
        count1 = count = k = 0;

        printf("\n");
    }
    return 0;
}

Result

* * * * * * * * *
  * * * * * * *
    * * * * *
      * * *
        *

但就我而言,我想做一个倒金字塔。询问星数后,我想制作金字塔形状。我无法决定将它塑造成倒金字塔形状的行数。

(不低于Exmaple仅供参考,不必遵循相同的模式,有人说,如果你有任何数量的开始,你将如何安排这些星形,使其形状像倒金字塔(这可能是不完整的),根据我想过打印下面的形状,但那些不统一)

**Case** :
1. User Enters :  9

 * * * * *
   * * *
     *

2. User Enters :  8

 * * * * 
  * * *
    *




3. User Enters :  7

 * * * * 
  * * *

 (No matter if shape completes or not, but it should print like this)

4. User Enters :  6

 * * *  
  * *
   *     

是否可以根据给定的星数来确定行数?

我将利用这个逻辑在scrollView中制作动态视图。

c logic
2个回答
3
投票

这将为您生成金字塔数组,同时尝试最小化每个层之间的差异,并保持对称性。

也许还有更多的优化要做,但这是我头脑中的第一个想法。

这是在Swift中可以在Swift Playground中运行,我以为我在OP的帖子下看到了一个Swift标签,但它现在显然被删除了,无论如何,代码本身很简单......

func genPyramid(count: Int) -> [Int] {
    var result: [Int] = []
    var maxPossibleRow: Int

    // special case
    if count <= 2 {
        return [count]
    }

    // test row diff: 1
    maxPossibleRow = Int(floor((sqrt(Float(8*count+1))-1.0)/2.0))
    if maxPossibleRow > 1 {
        let base = count - maxPossibleRow * (maxPossibleRow-1) / 2
        if base % maxPossibleRow == 0 {
            let firstRow = base / maxPossibleRow
            for k in 1...maxPossibleRow {
                result.append(firstRow + k - 1)
            }
            return result
        }
    }

    // test row diff: 2
    maxPossibleRow = Int(floor(sqrt(Float(count))))
    if maxPossibleRow > 1 {
        let base = count - 2 * maxPossibleRow * (maxPossibleRow-1) / 2
        if base % maxPossibleRow == 0 {
            let firstRow = base / maxPossibleRow
            for k in 1...maxPossibleRow {
                result.append(firstRow + 2*k-2)
            }
            return result
        }
    }

    // test row diff> 3
    for i in 3...count/2 {
        maxPossibleRow = Int(floor((Float(i-2)+sqrt(Float(i*i-4*i+4+8*i*count)))/2.0/Float(i)))
        print("looping", i, maxPossibleRow)
        if maxPossibleRow > 1 {
            let base = count - i * maxPossibleRow * (maxPossibleRow-1) / 2
            if base % maxPossibleRow == 0 {
                let firstRow = base / maxPossibleRow
                for k in 1...maxPossibleRow {
                    result.append(firstRow + i*(k-1))
                }
                return result
            }
        }
    }
    return []
}

一些测试用例fyr。 Demo


1
投票

那么,你需要决定的是你想要构建的金字塔形状,规则是什么?对于特定数量的恒星,您可以在上面显示许多不同的方案,但它们并不遵循建立金字塔的设定模式。

例如,在第一个例子中你有3颗星跟随1颗星,但在最后一个例子中有3颗星跟随2颗星。对于这种依赖于星星数量的特殊金字塔设计,您可能需要对其进行一些硬编码。

但是,如果您想为要构建的金字塔提供更精确的定义,例如,每个图层的下层不应超过1星,那么您可以设置算法来查找数字任意数量的星的行数。

这个算法似乎是一个非常好的开始,甚至可能正是你想要的:

int main(void)
{
    // creating two variables
    int num;

    printf("Enter num stars: ");
    scanf("%d", &num);
    printf("\n");

    int i = 0;

    while (num > i) {
        i++;
        num -= i;
    }

    printf("%d rows\n", i);

    return 0;
}

我是在认识到在一个perfect金字塔中,每行只有一颗星相同的时候建造它的,每一行中的恒星与该行的水平完全相同。该点有1颗星,下一行有2颗,接下来有3颗等...

因此,如果你计算行并减去一些等于你刚才计算的行的星数,并继续这样做,直到你没有足够的星星来形成一个完整的行,你将得到适当的行数。应将剩余的星号添加到现有行而不是创建新行。

© www.soinside.com 2019 - 2024. All rights reserved.