第一印象 我得到了和他一样的解法,就是用斜切片,每一层的 x-1和y+1 来控制顺序写数字的笔落在哪一个坐标。
但是根据一段时间的观察 我发现了几个规律 可以让我们不用模拟整个顺序的流
首先我们观察每一个切片
1 | 3 | 4 | 10 | 11 | 21 | 22 | 36 | 37 | 55 |
2 | 5 | 9 | 12 | 20 | 23 | 35 | 38 | 54 | 56 |
6 | 8 | 13 | 19 | 24 | 34 | 39 | 53 | 57 | 72 |
7 | 14 | 18 | 25 | 33 | 40 | 52 | 58 | 71 | 73 |
15 | 17 | 26 | 32 | 41 | 51 | 59 | 70 | 74 | 85 |
16 | 27 | 31 | 42 | 50 | 60 | 69 | 75 | 84 | 86 |
28 | 30 | 43 | 49 | 61 | 68 | 76 | 83 | 87 | 94 |
29 | 44 | 48 | 62 | 67 | 77 | 82 | 88 | 93 | 95 |
45 | 47 | 63 | 66 | 78 | 81 | 89 | 92 | 96 | 99 |
46 | 64 | 65 | 79 | 80 | 90 | 91 | 97 | 98 | 100 |
继续观察 又发现规律了。 这个矩阵对角对称的任意两个格子 正好是距离整个数列中心距离相等的两点 比如1和100 20和81 他们的和必为 max*max +1
这样我们只要能推算出某一行或者某一列的值 就可以通过上面两个特征来生成整个矩阵了哦
但是这个矩阵的行列太乱了 很难找出规律 这个时候就要考虑更简单的模型
我们看看非首尾接力的矩阵
1
1 2
3
1 2 4
3 5
6
1 2 4 7
3 5 8
6 9
10
有没有发现 粗体的数字 刚好是之前所有斜切片的总和?
那么 顺序矩阵和接力矩阵 有什么异同呢?
1 | 3 | 4 | 10 | 11 | 21 | 22 | 36 | 37 | 55 |
2 | 5 | 9 | 12 | 20 | 23 | 35 | 38 | 54 | 56 |
6 | 8 | 13 | 19 | 24 | 34 | 39 | 53 | 57 | 72 |
7 | 14 | 18 | 25 | 33 | 40 | 52 | 58 | 71 | 73 |
15 | 17 | 26 | 32 | 41 | 51 | 59 | 70 | 74 | 85 |
16 | 27 | 31 | 42 | 50 | 60 | 69 | 75 | 84 | 86 |
28 | 30 | 43 | 49 | 61 | 68 | 76 | 83 | 87 | 94 |
29 | 44 | 48 | 62 | 67 | 77 | 82 | 88 | 93 | 95 |
45 | 47 | 63 | 66 | 78 | 81 | 89 | 92 | 96 | 99 |
46 | 64 | 65 | 79 | 80 | 90 | 91 | 97 | 98 | 100 |
我们可以把接力矩阵当成隔行反转的顺序矩阵。这样我们就得到了一个在 x,y轴上摆动的参考值。 有了参考值 就可以根据前两点进行矩阵生成了
Code
static void Main(string[] args)
{
var max = 11;
int [,] mx=new int [max,max];
var sideval = 0;
for (var seed = 0; seed < max; seed++)
{
int parevalue = (seed + 1) * (seed + 1) + 1;//规律1 中心轴对称两数之和等于层数平方+1
bool isOdd = seed % 2 == 1;
sideval = sideval + seed + 1; //规律2 两边至少有一个数字为 1+2+3+4++n
for (var fillseed = seed; fillseed >=0; fillseed--)
{
int row, col;
if (!isOdd)
{
row = fillseed;
col = seed - fillseed;
}
else
{
col = fillseed;
row = seed - fillseed;
}
//规律1 中心轴对称两数之和等于层数平方+1
mx[col, row] = sideval - fillseed;
mx[row, col] = parevalue - mx[col, row];
//规律3 中心对称的和为 max*max+1
mx[max - col - 1, max - row - 1] = max * max +1 - mx[col, row];
mx[max - row - 1, max - col - 1] = max * max + 1 - mx[row, col];
}
}
for (var x = 0; x < max; x++)
{
for (var y = 0; y < max; y++)
{
Console.Write(string.Format (" {0:d3}" ,mx[x, y]));
}
Console.WriteLine();
}
Console.Read();
}
解法有很多种 这种无疑是很生涩的。 作为面试题目的话 并不建议写这种考官很难理解的解法,会有小鞋
作为头脑风暴 防止老年痴呆 这个还是有一定意义的
转载于:https://www.cnblogs.com/waynebaby/archive/2009/07/25/1530653.html