算法思路:
(思路来源http://hi.csdn.net/quietwave博主的回答)
对于这类打印方阵的问题,可以用数学的方法,推导出a[i][j] = F(i,j)中的F,即将第i行,第j列的元素用
i和j 的函数表示出来
然后再
for(int i = 0 ; i < n;i++)
{
for(int j = 0 ; j < n;j++)
printf("%5d ",getElement(i,j)); printf("/n");
}
关键是完成函数
int getElement(int i,int j);
对于这道题,
可以看出每条副对角线上有 i+j 为常量这个特点
所以可以想象第N条副对角线之前一定有
Sum = 1+2+...+N = N*(N+1)/2 个数字
然后再考虑副对角线i+j的奇偶性,
是奇数则从i=0开始填数,所以a[i][j] = sum + i + 1;
是偶数则有 a[i][j] = sum + j + 1;
方阵改变方向后,则将上面判断奇偶反过来,即可打印
#include <iostream> #include <cstdio> #include <math.h> using namespace std; /* **************************************************** haiping@ubuntu:~/program/yv0928$ ./a.out n = 6 1 3 4 10 11 21 2 5 9 12 20 22 6 8 13 19 23 30 7 14 18 24 29 31 15 17 25 28 32 35 16 26 27 33 34 36 *************************************************** */ /* *********************************** //获得n*n方阵中第i行第j列个元素 int getElement1(int i ,int j,int n) { int num = i+j; int sum = num * (num+1) >>1; //过了对角线要另行处理 //原作中这里还是有bug,过了对角线,n=3,5,7等后面就不对了 if(num > n-1) sum -= (num - n + 1) * (num - n + 1); //将判定条件改成 if(!(num&1)),改变方向 if(!num & 1) return sum + j+1; return sum + i+1; } ************************************ */ /*获得n*n方阵中第i行第j列个元素*/ int getElement1_m(int i ,int j,int n) { int num = i+j; int sum = num * (num+1) >>1; int s = n*n; //过了对角线要另行处理 if(num > n-1) { int t = 2*(n-1)-(i+j)+1; s-= t*(t+1)>>1; } //将判定条件改成 if(!(num&1)),改变方向 if(num & 1) return num > n-1?s +(n-i):sum + j+1; return num > n-1?s + (n-j):sum + i+1; } /* **************************************************** haiping@ubuntu:~/program/yv0928$ ./a.out n = 6 1 2 3 4 5 6 20 21 22 23 24 7 19 32 33 34 25 8 18 31 36 35 26 9 17 30 29 28 27 10 16 15 14 13 12 11 *************************************************** */ int getElement2(int i,int j,int n) { int k = min(min(i,j),n-1-max(i,j)); int sum = 4 * ( k * (n + 1) - k * (k+1)); /*将判定条件改成 if(j <= i)改变方向*/ if(j >= i) sum += (i+j) - 2*k + 1; else sum += ( n - 2*k - 1) * 4 - (i+j) + 2*k + 1; return sum; } /* **************************************************** haiping@ubuntu:~/program/yv0928$ ./a.out n = 5 2 2 2 2 2 2 1 1 1 2 2 1 0 1 2 2 1 1 1 2 2 2 2 2 2 *************************************************** */ int getElement3(int i,int j,int n) { //n 为任意正奇数 int mid = n/2; return max(abs(i-mid) , abs(j-mid)); } int main() { int n; int i,j; printf(" n = "); scanf("%d",&n); for(i = 0 ; i < n;i++){ for(j = 0 ; j < n;j++) printf("%-5d ",getElement2(i,j,n)); printf("\n"); } return 0; }