我怎么能做一个空三角形与明星在c++后做英国国旗?

k5hmc34c  于 2023-06-07  发布在  其他
关注(0)|答案(5)|浏览(359)

这是我在最后必须得到的标志:

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

我知道如何做完整的星星三角形,但当它的内部是空的,我不知道如何进行。谁能帮帮我?
我试过了,我只知道如何做完整的星星三角形和一个星形正方形/矩形里面是空的,这里是代码:

int main(void)
{
    int i, j, length, width;

    cout << "Length of rectangle? ";
    cin >> length;
    cout << endl;

    cout << "Width of rectangle? ";
    cin >> width;
    cout << endl;

    for ( i = 0; i < length; i++ )
        cout << "*";

    cout << endl;

    for ( i = 1; i < width - 1; i++ )
    {
        cout << "*";

        for ( j = 1; j < length - 1; j++ )
        {
            cout << " ";
        }

        cout << "*";
        cout << endl;
    }

    for ( i = 0; i < length; i++)
        cout << "*";

    cout << endl;

    return 0;
}
ztyzrc3y

ztyzrc3y1#

11019很简单,因为它们每个都只包含19 *
问题是291119这两行。
但是,您是否注意到29行中的模式?
线2由一个*组成

  • 后接0空格
  • 然后是一个*
  • 后接7空格
  • 然后是一个*
  • 后接7空格
  • 然后是一个*
  • 后接0空格

然后是一个*
线3由一个*组成

  • 后接1空格
  • 然后是一个*
  • 后接6空格
  • 然后是一个*
  • 后接6空格
  • 然后是一个*
  • 后接1空格

然后是一个*
线4由一个*组成

  • 后接2空格
  • 然后是一个*
  • 后接5空格
  • 后接一个*
  • 后接5空格
  • 后接一个*
  • 后接2空格

然后是一个*
线5由一个*组成

  • 后接3空格
  • 然后是一个*
  • 后接4空格
  • 然后是一个*
  • 后接4空格
  • 然后是一个*
  • 后接3空格

然后是一个*
线6由一个*组成

  • 后接4空格
  • 后接一个*
  • 后接3空格
  • 后接一个*
  • 后接3空格
  • 后接一个*
  • 后接4空格

然后是一个*
线7由一个*组成

  • 后接5空格
  • 然后是一个*
  • 后接2空格
  • 后接一个*
  • 后接2空格
  • 然后是一个*
  • 后接5空格

然后是一个*
线8由一个*组成

  • 后接6空格
  • 后接一个*
  • 后接1空格
  • 后接一个*
  • 后接1空格
  • 然后是一个*
  • 后接6空格

然后是一个*
线9由一个*组成

  • 后接7空格
  • 后接一个*
  • 后跟0空格
  • 后接一个*
  • 后跟0空格
  • 后接一个*
  • 后跟7空格

然后是一个*
模式如下:
假设size是三角形的总大小(在本例中为19),则
n由一个*组成

  • 后跟n-2空格
  • 后接一个*
  • 后接(size/2) - n空格
  • 然后是一个*
  • 后接(size/2) - n空格
  • 后接一个*
  • 后接n-2空格

然后是一个*
注意,在C中,19 / 2的结果是9,因为除法的小数部分被丢弃。
使用关于模式的这些信息,您应该能够创建一个循环,在每个循环迭代中,如上所述打印一行。通过这种方式,您应该能够解决打印29行的问题。
之后打印1119行应该很容易,因为这些行必须只按照29行的相反顺序打印。
根据community guidelines for homework questions,我不会在这个时候提供完整的解决方案。如有需要,我稍后可提供进一步资料。
编辑:
由于其他用户已经发布了几个其他解决方案,我现在也将发布我的解决方案,它解决了上述问题:

#include <iostream>

const int MAP_SIZE = 19;

static_assert( MAP_SIZE % 2 == 1, "MAP_SIZE must be odd" );

int main( void )
{
    //print first horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';

    //print top half of flag
    for ( int i = 0; i < MAP_SIZE / 2 - 1; i++ )
    {
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        std::cout << '\n';
    }

    //print second horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';

    //print bottom half of flag
    for ( int i = 0; i < MAP_SIZE / 2 - 1; i++ )
    {
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        std::cout << '\n';
    }

    //print third horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';
}

然而,我认为使用2D数组(您声明不允许使用)更容易解决这个问题。将2D数组初始化为空格,然后绘制3条水平线、3条垂直线和2条对角线:

#include <iostream>

const int MAP_SIZE = 19;

static_assert( MAP_SIZE % 2 == 1, "MAP_SIZE must be odd" );

int main( void )
{
    char map[MAP_SIZE][MAP_SIZE];

    //initialize 2D array to spaces
    for ( int i = 0; i < MAP_SIZE; i++ )
        for ( int j = 0; j < MAP_SIZE; j++ )
            map[i][j] = ' ';

    //draw the 3 horizontal lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[         0][i] = '*';
        map[MAP_SIZE/2][i] = '*';
        map[MAP_SIZE-1][i] = '*';
    }

    //draw the 3 vertical lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[i][         0] = '*';
        map[i][MAP_SIZE/2] = '*';
        map[i][MAP_SIZE-1] = '*';
    }

    //draw the 2 diagonal lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[i][           i] = '*';
        map[i][MAP_SIZE-i-1] = '*';
    }

    //print the result
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        std::cout.write( map[i], MAP_SIZE );
        std::cout.put( '\n' );
    }
}
yxyvkwin

yxyvkwin2#

把十字架放在中间很容易:

if (i == ??? || j == ???)
    std::cout << '*';
else
    std::cout << ' ';

诊断稍微有点棘手。
在嵌套循环中,输出std::cout << (i+j) << '\t'。你能从这些数字中看出什么规律来确定其中一条对角线吗?
然后对i-j重复同样的操作。你看到另一条对角线的图案了吗?
最后,你的嵌套循环看起来像这样:

if (i == /*something*/ || j == /*something else*/ || i+j .../*some condition*/ || i-j .../*another condition*/)
    std::cout << '*';
else
    std::cout << ' ';
zpgglvta

zpgglvta3#

示例(基于我30多年前参加的2D计算机图形课程的知识)。使用一维向量(动态分配数组)作为内存缓冲区和Bresenham线算法
现场演示:https://onlinegdb.com/Kg9HAdxfZ

#include <cassert>
#include <iostream>
#include <vector>

class Flag
{
public:
    Flag(int width, int height) :
        m_width{ width },
        m_height{ height },
        m_grid(width*height,false) // allocate buffer and clear to false
    {
        assert(width > 1);
        assert(height > 1);

        int w = width - 1;
        int h = height - 1;

        // outline of flag
        line(0, 0, w, 0);
        line(w, 0, w, h);
        line(w, h, 0, h);
        line(0, h, 0, 0);

        // diagonals
        line(0, 0, w, h);
        line(0, h, w, 0);

        // mid lines horizontal and vertical
        line(0, h / 2, w, h / 2);
        line(w / 2, 0, w / 2, h);
    };

    bool get(int x, int y) const
    {
        return m_grid.at(y * m_width + x);
    }

    int width() const noexcept
    {
        return m_width;
    }

    int height() const noexcept
    {
        return m_height;
    }

private:
    void set(int x, int y)
    {
        m_grid.at(y * m_width + x) = true;
    }

    // Bresenham's line algorithm 
    // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
    void line(int x0, int y0, int x1, int y1)
    {
        int dx = abs(x1 - x0);;
        int sx = x0 < x1 ? 1 : -1;
        int dy = -abs(y1 - y0);
        int sy = y0 < y1 ? 1 : -1;
        int error = dx + dy;

        while (true)
        {
            set(x0, y0);
            if ((x0 == x1) && (y0 == y1)) break;

            int e2 = 2 * error;
            if (e2 >= dy)
            {
                if (x0 == x1) break;
                error = error + dy;
                x0 = x0 + sx;
            }
            if (e2 <= dx)
            {
                if (y0 == y1) break;
                error = error + dx;
                y0 = y0 + sy;
            }
        }
    }

private:
    int m_width;
    int m_height;
    
    // a buffer to hold true/false for each posision of the m_grid
    // think pixels ;)
    std::vector<bool> m_grid;
};

std::ostream& operator<<(std::ostream& os, const Flag& flag)
{
    for (int y = 0; y < flag.height(); ++y)
    {
        for (int x = 0; x < flag.width(); ++x)
        {
            if (flag.get(x, y))
            {
                os << "*";
            }
            else
            {
                os << " ";
            }
        }
        std::cout << "\n";
    }
    
    return os;
}

int main()
{
    Flag flag(47, 15);
    std::cout << flag;
    return 0;
}
rekjcdws

rekjcdws4#

而不是在循环中计算每一行。让一个函数返回在每个点绘制的内容。然后你可以应用一些基本的代数来决定是否有一个点要画。

#include <iostream>

char getPoint(int width, int height, int x, int y) {
    int xNorm = (x <= width / 2) ? x : (width - x);
    int yNorm = (y <= height / 2) ? y : (height - y);

    // borders
    if ( ((x == 0) || (x == (width)) || (y == 0) || (y == height)) ||  // borders
         ((x == width / 2) || (y == height / 2)) ||                    // middle stripe
         ((width >= height) && (yNorm == xNorm * height / width)) ||   // diagnols (when width >= height)
         ((height > width) && (xNorm == yNorm * width / height))       // diagnols (when height > width)
        )
    {
        return '*';
    }
    return ' ';
}

void printFlag(int width, int height) {
    for (int y = 0; y <= height; y++) {
        for (int x = 0; x <= width; x++) {
            std::cout << getPoint(width, height, x, y);
        }
        std::cout << std::endl;
    }
}

int main()
{
    int height = 18;
    int width = 18;
    printFlag(width, height);
    return 0;
}

上面的打印:

*******************
**       *       **
* *      *      * *
*  *     *     *  *
*   *    *    *   *
*    *   *   *    *
*     *  *  *     *
*      * * *      *
*       ***       *
*******************
*       ***       *
*      * * *      *
*     *  *  *     *
*    *   *   *    *
*   *    *    *   *
*  *     *     *  *
* *      *      * *
**       *       **
*******************
y53ybaqx

y53ybaqx5#

void DrawUKflag(int L, int W)
{

    for (int i = 0; i <=L; i++)
    {
        for (int k = 0; k <=W; k++) 
        {
            if (i==0||i==L/2||i==L ||k==0||k==W/2||k==W)
            {
                cout << "*";
            }
            else if (k==W-i || k==i)
            {
                cout << "*";
            }
            else
            {
                cout << " ";
            }
        }
        cout << endl;
    }
}

相关问题