转圈矩阵的算法:鄙人写了一个傻瓜式的,
昨天下午在论坛看某人贴了一个这个问题后,很好奇这个东西,就一直想.....无奈本人毕业三年,什么东西都忘记了, 前几天才重新拿起书,重新复习;所以很艰难啊思索了一个小时无果后,果断睡觉,可是睡着睡着,突然来了感觉,,就开始写代码,,,午夜写完后,运行下,有错,果断睡觉,; 今天早上起来,重新修改,仔细的想了过程,归纳了下,,终于搞定啊,,,心里还是蛮高兴的啊......
以下为代码,不是很简练,见笑了,感觉还是很傻瓜式的方法:
#include<stdio.h>
#include<math.h>
#define n 9 //改变N的值,可以改变这个矩阵的阶数:即每行为N个数可以改变,这个矩阵分奇偶数哦
//N矩阵的圈数等于N模2(中心对称点不算圈)
// 注意:每圈分为:"上行",到 "右列",再到 "下行",再到 "左列",结束
// K从0开始,第K圈时: 第K圈的每个数大致如下:从a[k][k]开始,到a[k+1][k]结束
// 第K圈: a[k][k]、、、、、->、、、、、a[k][n-1-k]
// a[k+1][k] 、
void main() // 、 a[k+1][k+1]、、> 、 |
{ // 、 、第(k+1)圈 、 \ /
int i,t,j,m,k; // / \ 、 、 、
int a[n][n]; // | 、、、、<、、、 、 、
a[0][0]=0; // 、 、
t=0; // a[n-1-k][k]、、、、<-、、、、、、 a[n-1-k][n-1-k]
m=n/2; // k的最大值为m-1
if(n==1) printf("n不能为1!你可以自己手工画矩阵看,此时为一个点\n");
else
{
k=0; //K,m表示圈数k表示的是每次循环赋值时的实时圈数 m表示的是总圈数
for(j=1;j<=m;j++) //J,k表示这个循环要对第几圈进行赋值,k从0开始直到k变为等于m-1结束(此时j==m,注意:是J先等于m 然后k才结果一轮循环后等于m-1)
{ //因为每行和相邻的列有重合点,所以特别要注意 每行或 每列 的第一个数的赋值的特殊性
for(t=k;t<n-1-k;t++) //上行 :只输入第k个到第n-2-k个数,即只赋值n-1-2k个数! 从左到右
if(t==0&&k==0) a[k][t]++; // 特殊点:每轮只执行一次
else a[k][t]=a[k][t-1]+1;
for(i=k;i<n-k-1;i++) //右列 对 第n-k-1列赋值 从上到下
if(i==k) a[i][n-1-k]=a[i][n-1-k-1]+1; //特殊点:对 该列 第一个数赋值,该循环只执行一次这个语句
else a[i][n-1-k]=a[i-1][n-1-k]+1;
for(i=n-k-1;i>=k;i--) //下行 对 第n-k-1 行赋值 从右到左
if(i==n-k-1) a[n-1-k][i]=a[n-1-k-1][i]+1; //特殊点:对 该行 第一个数赋值,该循环只执行一次这个语句
else a[n-1-k][i]=a[n-1-k][i+1]+1;
for(i=n-2-k;i>k;i--) //左列 对 第k 列赋值,从下往上
a[i][k]=a[i+1][k]+1;
k++;
}
if(n%2==1) //当它是奇数时,矩阵有一个中心点a[m][m]还没赋值;;;当它是偶数时,没有中心点
a[m][m]=a[m][m-1]+1; //(中心点:这个矩阵以这个中心点为对称中心,每个数都存在一个和它相对称的数)
for(i=0;i<n;i++) //输出整个矩阵
{
for(j=0;j<n;j++)
printf("%2d ",a[i][j]);
putchar('\n');
}
} //其他方向循环:调整下赋值循序和数组的行标列标即可:例如顺时针变为逆时针
}