链接:https://ac.nowcoder.com/acm/contest/86/A
来源:牛客网
题目描述
Eteˊreo 总是对数字的神秘感感到好奇。这次,他在纸上写下了 K*K 个从 1到 K*K 的数字,并把这些数字排成了 K×K的方阵。他惊奇地发现,这个方阵中每行、每列和两条主对角线上的数字之和都不一样。他想要更多的方阵,但他再写不出来了。于是他㕛跑来找你,请你给他一个边长为 K的满足上述性质的方阵。
输入描述:
输入共一行,一个整数 K ,意义同题面描述。
输出描述:
输出共 K 行,每行 K个整数,表示答案方阵。 输出任意一种可行方案即可。
示例1
输入
3
输出
1 2 3 8 9 4 7 6 5
备注:
3≤K≤1000
题解:
每次随机一个矩阵,然后去check,知道满足条件的时候结束,因为矩阵中数字1到K*K每个数字出现一次,所以先把1到K*K放到
一个数组里,然后用 random_shuffle() 函数打乱,srand(time(0));播种,不播种也能过。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1005;
int a[maxn*maxn];
int g[maxn][maxn];
int n;
bool check(){
int cnt=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
g[i][j]=a[cnt++];
}
}
unordered_set<int> s;
for(int i=1;i<=n;i++){
int sum=0,sum2=0;
for(int j=1;j<=n;j++){
sum+=g[i][j];
sum2+=g[j][i];
}
if(s.count(sum)) return false;
s.insert(sum);
if(s.count(sum2)) return false;
s.insert(sum2);
}
int sum=0,sum2=0;
for(int i=1;i<=n;i++){
sum+=g[i][i];
sum2+=g[i][n-i+1];
}
if(s.count(sum)) return false;
s.insert(sum);
if(s.count(sum2)) return false;
return true;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n*n;i++) a[i]=i+1;
srand(time(0));
while(true){
random_shuffle(a,a+n*n);
if(check()){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d ",g[i][j]);
}
printf("\n");
}
break;
}
}
return 0;
}