来自代码
int count = 0;
for(int i=1; i<=n; i++)
for(int j=1; j<=2*n; j=j+2)
for(int k=i; k<=j; k++)
count++;
可以将其转换为语义等价的:
int count = 0;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
for(int k=i; k<=2*j - 1; k++)
count++;
如果在两个代码版本的末尾打印 count 变量,其值将是:
| loop 1 | loop 2
________________________________
N = 1 | 1 | 1
N = 2 | 6 | 6
N = 3 | 19 | 19
N = 4 | 43 | 43
N = 5 | 82 | 82
您从第二个循环中提取了公式:
这在纸上是有道理的,但是,有一个问题。将公式转换为代码:
public static int third_loop(int n ){
int count = 0;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
count += (2 * j - 1) - i + 1;
return count;
}
并显示变量count的值:
| loop 1 | loop 2 | loop 3
____________________________________
N = 1 | 1 | 1 | 1
N = 2 | 6 | 6 | 6
N = 3 | 19 | 19 | 18
N = 4 | 43 | 43 | 40
N = 5 | 82 | 82 | 75
count 的值现在不同了,其原因是会有 (2 * j - 1) count。在第二个循环中隐含地避免了一些事情。如果有人将第三个循环更改为:
public static int fourth_loop(int n ){
int count = 0;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
count += Math.max((2 * j - 1) - i + 1, 0);
return count;
}
一个人会得到:
| loop 1 | loop 2 | loop 3 | loop 4
__________________________________________
N = 1 | 1 | 1 | 1 | 1
N = 2 | 6 | 6 | 6 | 6
N = 3 | 19 | 19 | 18 | 19
N = 4 | 43 | 43 | 40 | 43
N = 5 | 82 | 82 | 75 | 82
因此,您的公式的问题在于它还考虑了负值,而您的代码则没有。因为,我没有数学工具给你精确的公式,所以我请math.stackexchange 的朋友这样做。
编辑:从我提供的赏金中,Matthew Towers 得出了以下精确表达式: