题目链接:
http://codeforces.com/contest/710/problem/C
题意:
给出1~n^2个数,将其填入n*n的矩阵,并保证每行每列,主对角线的和都为奇数。(n为奇数)
题解:
纠结于数学之美,在这个水题上卡了半天。
因为偶+偶=偶;奇+奇=偶,所以保证每行每列有一个奇数就可以了。其他数字都对称地填进去。(易证,剩余数能被4整除)
先生成一个十字型,之后找空格,有空的就对称填4个。结束
代码:
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 60
#define MAXM 3000
int a[MAXN][MAXN];
int odd[MAXM];
int even[MAXM];
int op,ep;
int T;
void Init() {
memset(a,0,sizeof(a));
memset(odd,0,sizeof(odd));
memset(even,0,sizeof(even));
op=0,ep=0;
for(int i=1; i<=T*T; i++) {
if(i&1) odd[++op]=i;//奇数
else even[++ep]=i;
}
}
int cd,cp;
void cross() {
int pp=(T+1)/2;
for(int i=1; i<=T; i++)
a[pp][i]=odd[++cd];
for(int i=1; i<=T; i++)
if(!a[i][pp])
a[i][pp]=odd[++cd];
}
void odd_put() {
for(int i=1; i<=T; i++) {
if(cd>(T*T+1)/2) break;
for(int j=1; j<=T; j++)
if(!a[i][j]) {
a[i][j]=odd[++cd];
a[i][T-j+1]=odd[++cd];
a[T-i+1][j]=odd[++cd];
a[T-i+1][T-j+1]=odd[++cd];
}
}
}
void even_put() {
for(int i=1; i<=T; i++)
for(int j=1; j<=T; j++)
if(!a[i][j])
a[i][j]=even[++cp];
}
void out() {
for(int i=1; i<=T; i++) {
for(int j=1; j<=T; j++) {
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("\n");
}
int main() {
while(cin>>T) {
cd=0;
cp=0;
Init();
cross();
odd_put();
even_put();
out();
}
return 0;
}