Educational Codeforces Round 16 C. Magic Odd Square

9 篇文章 0 订阅


C. Magic Odd Square
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Find an n × n matrix with different numbers from 1 to n2, so the sum in each row, column and both main diagonals are odd.

Input

The only line contains odd integer n (1 ≤ n ≤ 49).

Output

Print n lines with n integers. All the integers should be different and from 1 to n2. The sum in each row, column and both main diagonals should be odd.

Examples
input
1
output
1
input
3
output
2 1 4
3 5 7
6 9 8

题意:给一个奇数n,用1~n*n填充一个n*n的矩阵,使得矩阵的每行每列每个对角线和为奇数。

思路:求都是奇数则结果不唯一。

首先常识奇数+奇数=偶数  偶数+偶数=偶数 奇数+偶数=奇数

所以每行或每列或对角线一定有奇数个奇数。

下面用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; 
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值