看到园子里有人在讨论这个问题:
http://www.cnblogs.com/Chinese-xu/archive/2010/03/14/1685741.html
http://www.cnblogs.com/hanyulcf/archive/2010/03/11/1683098.html
于是乎一时手痒,便自己也写了一个,基本原理如下:
-
用一个类似贪吃蛇的方式填充,以左->下->右->上的方向完成一轮填充外围一圈
-
进入内圈,继续以左->下->右->上的方向的方式填充,然后这样一圈圈的填充,直至填满位置。
1 |
2 |
3 |
4 |
12 |
13 |
14 |
5 |
11 |
16 |
15 |
6 |
10 |
9 |
8 |
7 |
1 |
2 |
3 |
4 |
5 |
16 |
17 |
18 |
19 |
6 |
15 |
24 |
25 |
20 |
7 |
14 |
13 |
22 |
21 |
8 |
13 |
12 |
11 |
10 |
9 |
static void Main(string[] args)
{
while (true)
{
int length = int.Parse(Console.ReadLine());
var data = new int[length, length];
Process(data, 1, 0, 0, length);
//在控制台上输出
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
Console.Write(data[i, j].ToString().PadRight(3));
}
Console.WriteLine();
}
}
}
static void Process(int[,] data, int startIndex, int startX, int startY, int length)
{
if (length <= 0) //两种特殊的数据,无需前进,直接出结果
{
return;
}
else if (length == 1)
{
data[startX, startY] = startIndex++;
return;
}
for (int i = 0; i < length; i++) //向左前进
{
data[startX, startY + i] = startIndex++;
}
for (int i = 0; i < length - 2; i++) //向下前进
{
data[startX + 1 + i, startY + length - 1] = startIndex++;
}
for (int i = 0; i < length; i++) //向右前进
{
data[startX + length-1, startY + length-1-i] = startIndex++;
}
for (int i = 0; i < length - 2; i++) //向上前进
{
data[startX + length - 2 - i, startY] = startIndex++;
}
Process(data, startIndex, startX + 1, startY + 1, length - 2); //下一轮填充
}
为了使代码易读,这里我采用的是递归的方式,其实这种尾递归编译器应该是会将其优化为循环的,如果对编译器不信任也是很容易将其转换为循环的(在外围加个while循环就可以了)。