先上code
#include <stdio.h>
int N;
int getNum(int x,int y){
int k=x+y-1;
int ans=1;
if(k==1)return ans;
for(int i=2;i<k;i++){
if(i<=N)ans+=i;
else ans+=N+N-i;
}
if(k%2!=0){
if(k<=N)ans+=y;
else ans+=y-(k-N);
}else{
if(k<=N)ans+=x;
else ans+=x-(k-N);
}
return ans;
}
int main(void){
scanf("%d",&N);
for(int i=1;i<=N;i++){
for(int j=1;j<N;j++){
printf("%d ",getNum(i,j));
}
printf("%d\n",getNum(i,N));
}
return 0;
}
思路如下:
题目要求打印矩阵,相关例子如下
N==1
1
N==2
1 2
3 4
N==3
1 2 6
3 5 7
4 8 9
N==4
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
N==5
1 2 6 7 15
3 5 8 14 16
4 9 13 17 22
10 12 18 21 23
11 19 20 24 25
不难发现,这些矩阵有一定的规律,先简化一下,只考虑1<=i,j<=N的情况
N==1
1
N==2
1 2
3
N==3
1 2 6
3 5
4
N==4
1 2 6 7
3 5 8
4 9
10
N==5
1 2 6 7 15
3 5 8 14
4 9 13
10 12
11
再简化一下,从斜线的角度入手,判断矩阵中x[i][j]处于第k斜线由k=i+j-1求得,分成一行一行
N==1
1
N==2
1
3 2
N==3
1
3 2
4 5 6
N==4
1
3 2
4 5 6
10 9 8 7
N==5
1
3 2
4 5 6
10 9 8 7
11 12 13 14 15
再再简化一下,不考虑数字的顺序
N==1
1
N==2
1
2 3
N==3
1
2 3
4 5 6
N==4
1
2 3
4 5 6
7 8 9 10
N==5
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
这样它就变成了我们熟悉的样子,OK,加上对角线后面的部分,也挺简单的是不是
N==1
1
N==2
1
2 3
4
N==3
1
2 3
4 5 6
7 8
9
N==4
1
2 3
4 5 6
7 8 9 10
11 12 13
14 15
16
N==5
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
16 17 18 19
20 21 22
23 24
25
1
假设到这里,可以得到,第i行第j列元素=前k斜线元素个数+第i行第j列元素的位置\
加上顺序
N==1
1
N==2
1
3 2 //逆序
4
N==3
1
3 2 //逆序
4 5 6
8 7 //逆序
9
N==4
1
3 2 //逆序
4 5 6
10 9 8 7 //逆序
11 12 13
15 14 //逆序
16
N==5
1
3 2 //逆序
4 5 6
10 9 8 7 //逆序
11 12 13 14 15
19 18 17 16 //逆序
20 21 22
24 23 //逆序
25
所以要计算第i行第j列个元素的值,我们需要考虑的问题有:
- 第k斜线
- 第1~k-1斜线的元素个数
- 顺序还是逆序
- x[i][j]处于顺序或逆序的第几个位置
- k>N的情况
int getNum(int x,int y){
int k=x+y-1; //第k斜线
int ans=1; //x[i][j]的值
if(k==1)return ans; //第1斜线
for(int i=2;i<k;i++){ //前k斜线的元素个数
if(i<=N)ans+=i;
else ans+=N+N-i; //k>N
}
if(k%2!=0){ //第k斜线是逆序
if(k<=N)ans+=y;
else ans+=y-(k-N); //k>N
}else{ //第k斜线是逆序
if(k<=N)ans+=x;
else ans+=x-(k-N); //k>N
}
return ans;
}

京公网安备 11010502036488号