蛇形填数(Java代码)
题目描述:
如下图所示,小明用从 1开始的正整数“蛇形”填充无限大的矩阵。
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?
1 2 6 7 15 ...
3 5 8 14 ...
4 9 13 ...
10 12 ...
11 ...
...
查看该图可以发现每一条斜线都是承递增或递减的趋势变化的,第一条斜线[1],第二条斜线 [2, 3] ,第三条 [6, 5, 4] ,第四条 [7, 8, 9, 10], 第五条 [15, 14, 13, 12, 11], 取每一条斜线的第一个元素也就是看数据的第一行,可以发现如下的规律
由 1(1) 位置到 2(2) 位置 ---> 加了 1
由 2(2) 位置到 3(6) 位置 ---> 加了 4 ( 2 - 1 + 3 )
由 3(6) 位置到 4(7) 位置 ---> 加了 1
由 4(7) 位置到 5(15) 位置 ---> 加了 8 ( 4 - 1 + 5 )
由 5(15) 位置到 6(16) 位置 ---> 加了 1
这样就可以推出第一行的每一个数的值与他所在的列数有关, 如果是奇数列到偶数列那么偶数列的值就是奇数列的值加 1, 如果是偶数列到奇数列那么奇数列的值就是加上 偶数列的列数减一 加 奇数列的数;
根据如上的规律可以写出如下代码
// i 为 当前的列数
if(i%2 == 0)
{
// 为偶数列就在前一列的基础上加1
result++;
}
else
{
// 奇数列就在前一列的基础上加上当前列的列数和前一列的列数减一
result += (i - 2) + i;
}
到这已经可以算出第一行的每一位数的值了, 剩下的就是算 [20, 20] 的值了.
先观察一下 [3, 3] 位置数所在的斜线位置.
如图可以看到 [3, 3] 的数落在 5 ( 3*2 - 1 ) 的位置上, 所以要求 [20, 20] 上的数需要先求得 39 ( 20x2 - 1 ) 列的数, 然后还能发现 [3, 3] 在斜线的中点上(这里就不画图了) . 而在一开始就说了斜线是承着递增或递减的趋势, 所以下一步就是判断结果所在的斜线是递增的还是递减的;
如图只要该数所在的列数为偶数的话他就是承递减趋势, 列数为奇数的话承递增的趋势,所以代码可以写成
// i当前列的列数
if(i%2 == 0)
{
// 偶数列承上升趋势
return result + (i/2);
}
else
{
// 奇数列承下降趋势
return result - (i/2);
}
要其他位置的数时也可以根据当前列的趋势和直线的斜率求该点所在的斜线得出.
以下为完整代码
static int snake_num(int x)
{
if(x == 1 || x == 2)
return x;
int result = 2;
int i = 3;
for(; i <= 2*x; i++)
{
if(i%2 == 0)
result++;
else
result += (i - 2) + i;
}
if(i%2 == 0)
return result + (i/2);
else
return result - (i/2);
}