使用尽可能少的 space 连续分配点数
Distribute points in a row using as little space as possible
我有一行最多可以包含 N
个点。我想在该行内从中心向外分配 x
点,使用尽可能少的 space.
我设法在行内均匀分配点,但它使用了所有可用的点 space。使用公式 floor((i+0.5)*N/x)
,我得到以下结果,考虑 N=9
:
4
2 6
1 4 7
1 3 5 7
0 2 4 6 8
0 2 3 5 6 8
0 1 3 4 5 7 8
0 1 2 3 5 6 7 8
0 1 2 3 4 5 6 7 8
以下是上面输出中显示的索引的示例图形表示:
我想基本上限制点从中心向外太远,所以我得到的结果更像:
4
3 5
3 4 5
2 3 5 6
2 3 4 5 6
1 2 3 5 6 7
1 2 3 4 5 6 7
0 1 2 3 5 6 7 8
0 1 2 3 4 5 6 7 8
以下是上面输出中显示的索引的示例图形表示:
我正在使用 Java,这是我当前的代码
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
for (float i = 0; i < points; i++) {
double result = Math.floor((i + 0.5) * rowLength / points);
System.out.print((int) result + " ");
}
System.out.println();
}
如何才能最好地实现第二张图片中显示的结果,以便我的代码输出与第二个示例输出相匹配?
好吧,我们看图吧。对我来说,似乎有几行有一些共同点:
观察:
- 蓝色线中间点填充,橙色线中间空。
- 蓝色的是奇数,橙色的是偶数。
- 左边的space是
- 在奇数情况下:
(rowLength - points)/2
,例如(9-1)/2 = 4
- 在偶数情况下:
(rowLength -points -1)/2
,例如(9-2-1)/2 = 3
让我们将其写入代码。我这里用的是C#,不过Java应该很像:
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
bool isOdd = points%2 == 1;
if (isOdd)
{
int spaceOnSide = (rowLength-points)/2;
for (int i=0; i<points;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
}
else // even
{
int spaceOnSide = (rowLength-1-points)/2;
for (int i=0; i<points/2;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
for (int i=points/2; i<points;i++)
{
Console.Write(""+(i+spaceOnSide+1)+" ");
}
}
Console.WriteLine();
}
正如观察告诉我们的那样,这非常简单。
鉴于该代码,我们可以使用一些技巧:
由于整数除法,行
int spaceOnSide = (rowLength-1-points)/2;
给出与
相同的结果
int spaceOnSide = (rowLength-points)/2;
(没有-1).
我们可以将奇数情况下的for循环分成两部分:
for (int i=0; i<points/2;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
for (int i=points/2; i<points;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
乍一看这听起来适得其反,但请看第 3 步。
完成更改后,奇数部分和偶数部分看起来非常相似。这真的是重复的代码。唯一的区别在于 +1
部分。我们可以在那里添加 if 语句作为三元运算符:
for (int i=0; i
如果你不喜欢三元运算符,你可以去掉它:
(isOdd?0:1)
等于
(points+1)%2
最后你的代码就这么简单
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
int spaceOnSide = (rowLength-points)/2;
for (int i=0; i<points/2;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
for (int i=points/2; i<points;i++)
{
Console.Write(""+(i+spaceOnSide+(points+1)%2)+" ");
}
Console.WriteLine();
}
我有一行最多可以包含 N
个点。我想在该行内从中心向外分配 x
点,使用尽可能少的 space.
我设法在行内均匀分配点,但它使用了所有可用的点 space。使用公式 floor((i+0.5)*N/x)
,我得到以下结果,考虑 N=9
:
4
2 6
1 4 7
1 3 5 7
0 2 4 6 8
0 2 3 5 6 8
0 1 3 4 5 7 8
0 1 2 3 5 6 7 8
0 1 2 3 4 5 6 7 8
以下是上面输出中显示的索引的示例图形表示:
我想基本上限制点从中心向外太远,所以我得到的结果更像:
4
3 5
3 4 5
2 3 5 6
2 3 4 5 6
1 2 3 5 6 7
1 2 3 4 5 6 7
0 1 2 3 5 6 7 8
0 1 2 3 4 5 6 7 8
以下是上面输出中显示的索引的示例图形表示:
我正在使用 Java,这是我当前的代码
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
for (float i = 0; i < points; i++) {
double result = Math.floor((i + 0.5) * rowLength / points);
System.out.print((int) result + " ");
}
System.out.println();
}
如何才能最好地实现第二张图片中显示的结果,以便我的代码输出与第二个示例输出相匹配?
好吧,我们看图吧。对我来说,似乎有几行有一些共同点:
观察:
- 蓝色线中间点填充,橙色线中间空。
- 蓝色的是奇数,橙色的是偶数。
- 左边的space是
- 在奇数情况下:
(rowLength - points)/2
,例如(9-1)/2 = 4 - 在偶数情况下:
(rowLength -points -1)/2
,例如(9-2-1)/2 = 3
- 在奇数情况下:
让我们将其写入代码。我这里用的是C#,不过Java应该很像:
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
bool isOdd = points%2 == 1;
if (isOdd)
{
int spaceOnSide = (rowLength-points)/2;
for (int i=0; i<points;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
}
else // even
{
int spaceOnSide = (rowLength-1-points)/2;
for (int i=0; i<points/2;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
for (int i=points/2; i<points;i++)
{
Console.Write(""+(i+spaceOnSide+1)+" ");
}
}
Console.WriteLine();
}
正如观察告诉我们的那样,这非常简单。
鉴于该代码,我们可以使用一些技巧:
由于整数除法,行
int spaceOnSide = (rowLength-1-points)/2;
给出与
相同的结果int spaceOnSide = (rowLength-points)/2;
(没有-1).
我们可以将奇数情况下的for循环分成两部分:
for (int i=0; i<points/2;i++) { Console.Write(""+(i+spaceOnSide)+" "); } for (int i=points/2; i<points;i++) { Console.Write(""+(i+spaceOnSide)+" "); }
乍一看这听起来适得其反,但请看第 3 步。
完成更改后,奇数部分和偶数部分看起来非常相似。这真的是重复的代码。唯一的区别在于
+1
部分。我们可以在那里添加 if 语句作为三元运算符:for (int i=0; i
如果你不喜欢三元运算符,你可以去掉它:
(isOdd?0:1)
等于
(points+1)%2
最后你的代码就这么简单
int rowLength = 9;
for (int points = 0; points <= rowLength; points++) {
int spaceOnSide = (rowLength-points)/2;
for (int i=0; i<points/2;i++)
{
Console.Write(""+(i+spaceOnSide)+" ");
}
for (int i=points/2; i<points;i++)
{
Console.Write(""+(i+spaceOnSide+(points+1)%2)+" ");
}
Console.WriteLine();
}