算法思路:
(思路来源http://hi.youkuaiyun.com/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;
(思路来源http://hi.youkuaiyun.com/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;
}