链接:https://www.nowcoder.com/acm/contest/86/A
题目描述
总是对数字的神秘感感到好奇。这次,他在纸上写下了 个从 到 的数字,并把这些数字排成了 的方阵。他惊奇地发现,这个方阵中每行、每列和两条主对角线上的数字之和都不一样。他想要更多的方阵,但他再写不出来了。于是他㕛跑来找你,请你给他一个边长为 的满足上述性质的方阵。
输入描述:
输入共一行,一个整数
,意义同题面描述。
输出描述:
输出共
行,每行
个整数,表示答案方阵。
输出任意一种可行方案即可。
备注:
思路:
1. 1~(n-1) 列,按行 依次填入数字。 n 列从第一行到第n行依次填入数字
2. 另类方法,随机法 ,原帖 https://blog.csdn.net/jeatiaime813/article/details/80034407
AC码:
1 #include <iostream> 2 using namespace std; 3 int main(){ 4 int n; 5 cin>>n; 6 int cnt=1,fine = n*n-n+1; 7 for(int i=0;i<n;i++) 8 for(int j=0;j<n;j++) 9 if(j==n-1) 10 cout<<fine++<<endl; 11 else 12 cout<<cnt++<<" "; 13 return 0; 14 }
随机大法:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<ctime> 5 #include<set> 6 using namespace std; 7 int a[1100][1100]; 8 int n; 9 void aaa() 10 { 11 for (int i = 1; i <= n; i++) 12 { 13 for (int j = 1; j <= n; j++) 14 { 15 if (j == n) printf("%d ", a[i][j]); 16 else printf("%d ", a[i][j]); 17 } 18 } 19 } 20 void hhh() 21 { 22 for (int i = 1; i <= n; i++) 23 for (int j = 1; j <= n; j++) 24 a[i][j] = (i - 1) * n + j; 25 for (int i = 1; i <= n; i++) 26 { 27 for (int j = 1; j <= n; j++) 28 { 29 int rx = rand() % n + 1; 30 int ry = rand() % n + 1; 31 swap(a[i][j], a[rx][ry]); 32 } 33 } 34 } 35 bool judge() 36 { 37 int r[1100], c[1100]; 38 int z1 = 0, z2 = 0; 39 memset(r, 0, sizeof(r)); 40 memset(c, 0, sizeof(c)); 41 for (int i = 1; i <= n; i++) 42 { 43 for (int j = 1; j <= n; j++) 44 { 45 r[i] += a[i][j]; 46 c[j] += a[i][j]; 47 if (i == j) z1 += a[i][j]; 48 if (i + j == n + 1) z2 += a[i][j]; 49 } 50 } 51 set<int> st; 52 for (int i = 1; i <= n; i++) 53 { 54 st.insert(r[i]); 55 st.insert(c[i]); 56 } 57 st.insert(z1); 58 st.insert(z2); 59 if ((int)st.size() == (2 * n + 2)) return true; 60 else return false; 61 } 62 int main() 63 { 64 srand((unsigned)time(NULL)); 65 while (scanf("%d", &n) != EOF) 66 { 67 if (n == 3) 68 { 69 printf("1 2 3 8 9 4 7 6 5 "); 70 } 71 else { 72 int maxtime = 10; 73 while (maxtime--) 74 { 75 hhh(); 76 if (judge()) break; 77 } 78 aaa(); 79 } 80 } 81 return 0; 82 }