绘图池 table 个球轨迹 w/o 个容器
Drawing pool table ball trajectory w/o containers
问题陈述如下:
描述:
写一个C++程序,读取水池table的尺寸,并以0打印球以45度角击中左上角table后的轨迹。
输入:
输入由多个案例组成,每个案例都有行数和列数。这两个数字至少都是 2。
输出:
打印每个池 table,如示例所示。
观察:
预期的解决方案不使用矢量等。这包括向量、字符串、数组等。从数学上讲,预期的解决方案在最坏的情况下使用 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#
##################
如果您可以使用一个矩阵来标记球在每次运动后的位置,并跟随它的轨迹直到它撞到一个角,那么这个问题的解决方案将相当容易。但是他们希望你不要使用这样的数据结构(这是一个入门编程课程,只是为了练习),所以它有点困难。
我想到了一个解决方案,它每行打印输出池 table 行,跟踪球的位置,但我遇到的主要问题是能够预测球的位置像第二个 (10, 16) 这样的情况,当你打印第一行时,你已经需要知道球在与 table.
碰撞后最终会再次到达它两次。
知道如何解决吗?
最简单的方法是预先分配要显示的字符串的缓冲区。或者:
- 一个std::strings的数组,字符串[y + some].
- 一个二维数组,char[y + some][x + some].
- 或者一个简单的字符数组,char[(x + some)*(y + some)].
+some 用于边框、'\0' 终端等...
您可能希望使用 new 动态分配它,以便您可以为每个 table 调整缓冲区大小。或者只是分配更大的东西来覆盖最大的 table.
然后,用空格填充缓冲区,并在数组中绘制边框。从 (0,0) 开始球,在未完成时进行迭代,将“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;
}
}
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 逻辑。从评论中获取的提示。
问题陈述如下:
描述:
写一个C++程序,读取水池table的尺寸,并以0打印球以45度角击中左上角table后的轨迹。
输入:
输入由多个案例组成,每个案例都有行数和列数。这两个数字至少都是 2。
输出:
打印每个池 table,如示例所示。
观察:
预期的解决方案不使用矢量等。这包括向量、字符串、数组等。从数学上讲,预期的解决方案在最坏的情况下使用 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#
##################
如果您可以使用一个矩阵来标记球在每次运动后的位置,并跟随它的轨迹直到它撞到一个角,那么这个问题的解决方案将相当容易。但是他们希望你不要使用这样的数据结构(这是一个入门编程课程,只是为了练习),所以它有点困难。
我想到了一个解决方案,它每行打印输出池 table 行,跟踪球的位置,但我遇到的主要问题是能够预测球的位置像第二个 (10, 16) 这样的情况,当你打印第一行时,你已经需要知道球在与 table.
碰撞后最终会再次到达它两次。知道如何解决吗?
最简单的方法是预先分配要显示的字符串的缓冲区。或者:
- 一个std::strings的数组,字符串[y + some].
- 一个二维数组,char[y + some][x + some].
- 或者一个简单的字符数组,char[(x + some)*(y + some)].
+some 用于边框、'\0' 终端等... 您可能希望使用 new 动态分配它,以便您可以为每个 table 调整缓冲区大小。或者只是分配更大的东西来覆盖最大的 table.
然后,用空格填充缓冲区,并在数组中绘制边框。从 (0,0) 开始球,在未完成时进行迭代,将“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;
}
}
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 逻辑。从评论中获取的提示。