思路:求都是奇数则结果不唯一。
首先常识奇数+奇数=偶数 偶数+偶数=偶数 奇数+偶数=奇数
所以每行或每列或对角线一定有奇数个奇数。
下面用1代表所有奇数,2代表所有偶数
3×3的情况
2 1 2
1 1 1
2 1 2
只有这一种。
5×5
可以是
1 2 1 2 1
2 2 1 2 2
1 1 1 1 1
2 2 1 2 2
1 2 1 2 1
开始就是这样想的,但是找不到一般性的规律。
后来就参考3×3的样子,扩展得到5×5
2 2 1 2 2
2 1 1 1 2
1 1 1 1 1
2 1 1 1 2
2 2 1 2 2
这样就可以依次扩展到n很大的时候了。
观察5×5可以看出值为奇数的位置跟中心的距离有种圆上的点到圆心的感觉。
只是欧几里德距离(sqrt((x1-x2)^2 + (y1-y2)^2))不适用,可以发现
奇数点到中心点两点横纵坐标差值的绝对值和都是小于等于2的。
这种距离可以查得到也有个数学名称叫曼哈顿距离,其实不需要知道定义也可以发现得了
计算方法。
这样只要遍历一下矩阵,到中心点曼哈顿距离<=n/2 的点填奇数,其它情况填偶数。
#include <cstdio>
#include <math.h>
const int N = 50;
using namespace std;
int rec[N][N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
// freopen("out.txt","w",stdout);
// ios::sync_with_stdio(0);
int n;
while (~scanf("%d", &n))
{
int odd = 1;
int even = 2;
int mid = n>>1; //位运算相当于除2
int m = mid + 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
int all = abs(i - m) + abs(j - m), out;
if (all <= mid)
{
out = odd;
odd += 2;
}else
{
out = even;
even += 2;
}
printf("%d%c", out, j == n?'\n':' ');
}
}
return 0;
}