一、什么是旋转方阵
1 8 7
2 9 6
3 4 5
形如上述,数字旋转入中心过程中逐渐递增的一个方阵就是旋转方阵。
二、求解旋转方阵的技巧与思路
在生成方阵中,我们可以采用逐层列数的方式解决。
一个3×3的方阵由内外两层,4×4的方阵也是如此。5×5的方阵则是有外、中、内三层。
采用逐层解决的原因是 每层数字列出规律都是类似的,大家在纸上可以观察到,都是先从左上角向下列,之后分别向右、上、左列到尽头。我们可以设计函数,每次执行函数使得最外层的数字列举完毕。
那么在设计函数中就有了问题:何时拐弯?不嫌麻烦的话可以判断[保持该方向走下去,下一个数字有没有越界],但这意味着每次向矩阵中填充数字,我们都得进行一次判断,这显然是浪费时间空间的。这个时候我们多列几个方阵就可以发现一些规律:
(1)首先观察到,任何方阵都是由一层层构成的。并且,外层比内层多两个数字。
(2)
我们发现不论边长为多少的外层,都可以通过四个长度为n-1的线贯穿。换言之,对于一个确定长度的外层,我们可以通过四次确定的列数(但四次列数的方向不一)填充整个外层。
三、具体代码实现与细节分析
void writecircle(int num){
//num = 4;
int i,j;
i = j = circle;
//writefirst
if(num==1){
a[i][j] = count;
return;
}
for(int t = 0; t < num-1 ; t++){
a[i++][j] = count++;
}
//-->
for(int t = 0; t < num-1 ; t++){
a[i][j++] = count++;
}
//↑
for(int t = 0; t < num-1 ; t++){
a[i--][j] = count++;
}
for(int t = 0; t < num-1 ; t++){
a[i][j--] = count++;
}
}
上述代码主要由四个for循环构成,每一个for循环使得我们可以向某个方向填充n-1个数字。
但需要注意,如果边长n=1,显然意味着来到了尽头,我们只需填充完数字即可,不需要执行for循环。
int main(void){
int num = 4;
while( num>0 ){
writecircle(num);
circle++;
num -= 2;
print();
printf("\n\n");
}
print();
}
对于初始边长为4的旋转方阵,每层长度递减2,并且逐层列写数字。