绘制台球桌球轨迹没有容器

时间:2015-01-20 13:33:46

标签: c++ drawing

问题陈述如下:

说明

编写一个C ++程序,读取一个台球桌的尺寸,然后以45°的角度撞击左上角的桌子,打印0球的轨迹。

输入:

输入由几种情况组成,每种情况都有行数和列数。这两个数字至少是2。

输出:

打印每个池表,如示例所示。

观察:

预期解决方案不使用矢量或类似。这包括向量,字符串,数组等。从数学上讲,预期的解决方案在最坏的情况下使用 O(1)内存

示例:

示例输入:

7 4
10 16

示例输出:

######
#0   #
# 0  #
#  0 #
#   0#
#  0 #
# 0  #
#0   #
######

##################
#0     0     0   #
# 0   0 0   0 0  #
#  0 0   0 0   0 #
#   0     0     0#
#  0 0   0 0   0 #
# 0   0 0   0 0  #
#0     0     0   #
# 0   0 0   0 0  #
#  0 0   0 0   0 #
#   0     0     0#
##################

如果您可以使用例如矩阵来保持在每次移动后标记球的位置,并遵循其轨迹直到它到达角落,那么这个问题的解决方案将相当容易。但他们希望你不要使用这样的数据结构(这是一个入门编程课程,只是为了练习),所以它有点困难。

我想过一个解决方案,每行打印输出池表格线,跟踪球位置,但我遇到的主要问题是能够在第二个位置预测球的位置( 10,16)当你打印第一行时,你需要知道在与桌子碰撞后球最终会再次到达两次。

有关如何解决它的想法吗?

3 个答案:

答案 0 :(得分:0)

最简单的方法是预先分配要显示的字符串的缓冲区。之一:

  • std :: strings数组,字符串[y + some]。
  • 二维数组,char [y + some] [x + some]。
  • 或简单的char数组,char [(x + some)*(y + some)]。

+一些用于边框,' \ 0'终端等... 您可能希望使用new动态分配它,以便您可以为每个表调整缓冲区大小。或者只是分配一些覆盖最大表的更大的东西。

然后,用空格填充缓冲区,并在数组中绘制边框。在(0,0)开始球,在你没有完成的情况下进行迭代,将“0”放在缓冲区中。完成后,逐行打印整个缓冲区。

答案 1 :(得分:0)

愚蠢地实施Jeffreys的建议。计算上很愚蠢,可能更容易用数学方法做到这一点,但它回答了这个问题......

bool SimulateBallUntil(int width, int height, int x, int y)
{
    // start off heading down right
    int xInc = 1;
    int yInc = 1;

    // Start off at pos 0,0
    int curX = 0;
    int curY = 0;

    // Run the path...
    for(int iter=0;;++iter)
    {
        // Check if hit point
        if(curX == x && curY == y)
        {
            return true;
        }

        // Check if hit corner (ignoring the first iteration which is the left corner)
        if(iter && ((curY == 0) || (curY == height-1)) && ((curX == 0) || (curX == width-1)))
        {
            return false;
        }

        // Bounce off walls
        if(curX + xInc == width || ((curX + xInc)==-1))
        {
            xInc *= -1;
        }
        if(curY + yInc == height || (curY + yInc==-1))
        {
            yInc *= -1;
        }

        // Move it
        curX += xInc;
        curY += yInc;

    }
}

答案 2 :(得分:0)

int positiveMod(int x, int y)
{
    return ((x % y) + y) % y;
}

int main()
{
    int x,y,sx,sy;
    int startX;
    int minStartX = 0;
    cin >> sy >> sx;

    startX = 0;

    // compute the various start points on x with y=0, keep the smallest to identify the repeating stride
    do
    {
        startX = (startX + 2 * (sy - 1)) % (2 * (sx - 1));
        if ((minStartX == 0) || (startX < minStartX) && (startX != 0))
        {
            minStartX = startX;
        }
    }
    while (startX != 0);


    for(y=0; y < sy; y++)
    {
        for(x=0; x < sx; x++)
        {
            if (
                    (minStartX == 0) && (x == y) || //identity line
                    (minStartX != 0) && positiveMod(x - y, minStartX) == 0 || // top-left quadrant
                    (minStartX != 0) && positiveMod( (2 * (sx - 1) - x) - y, minStartX) == 0 || // mirror against y axis
                    (minStartX != 0) && positiveMod( x - (2 * (sy - 1)) - y, minStartX) == 0 // mirror against x axis
                )
            {
                cout << '0';
            }
            else
            {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

它仍然需要边框,并且需要在y> x的情况下进行修复。在这种情况下,您只需翻转x / y逻辑。从评论中提取的提示。