hdu 3927 反幻方

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3927

看到网上的解题报告才知道反幻方有这性质,学习了。。。

定理:若n(n>=3)阶方阵为 A=[aij]

 

a[i][j]=(i-1)*(n-1)+j ;  (i=1,...n, j=1,....n-1)

 

a[i][j]=n*(n-1)+i;        (i=1,...n,j=n)

 

则A是一个n阶反幻方

http://www.cnblogs.com/xiaoxian1369/archive/2011/09/22/2184852.html

View Code
 1 #include<stdio.h>
2 #define nmax 201
3 int num[nmax][nmax];
4 void solve(int n) {
5 int i, j, k;
6 for (i = 0, k = 1; i < n; i++) {
7 for (j = 0; j < n - 1; j++) {
8 num[i][j] = k, k++;
9 }
10 }
11 for (i = 0; i < n; i++) {
12 num[i][n - 1] = k, k++;
13 }
14 }
15 int main() {
16 int t, k, i, j, n;
17 while (~scanf("%d", &t)) {
18 for (k = 1; k <= t; k++) {
19 scanf("%d", &n);
20 solve(n);
21 printf("Case #%d:\n", k);
22 for (i = 0; i < n; i++) {
23 printf("%d", num[i][0]);
24 for (j = 1; j < n; j++) {
25 printf(" %d", num[i][j]);
26 }
27 printf("\n");
28 }
29 }
30 }
31 return 0;
32 }

 还有一个哥们比较牛逼,用随机生成矩阵来构造反幻方

View Code
 1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
5 #include <set>
6 using namespace std;
7 #define maxn 210
8
9 int a[maxn][maxn];
10 int n;
11
12 int judge(){
13 int i,j,sum;
14 set<int> s;
15 for(i=1; i<=n; i++){
16 sum=0;
17 for(j=1; j<=n; j++)
18 sum+=a[i][j];
19 s.insert(sum);
20 sum=0;
21 for(j=1; j<=n; j++)
22 sum+=a[j][i];
23 s.insert(sum);
24 }
25 sum=0;
26 for(i=1; i<=n; i++)
27 sum+=a[i][i];
28 s.insert(sum);
29 sum=0;
30 for(i=1; i<=n; i++)
31 sum+=a[i][n-i+1];
32 s.insert(sum);
33 return s.size();
34 }
35
36 intmain(){
37 int i,j,tem,T,cas;
38 int x1,x2,y1,y2;
39 scanf("%d",&T);
40 for(cas=1; cas<=T; cas++){
41 scanf("%d",&n);
42 printf("Case #%d:\n",cas);
43 for(i=1; i<=n; i++)
44 for(j=1; j<=n; j++)
45 a[i][j]=(i-1)*n+j;
46 srand((unsigned)time(NULL));
47 while(1){
48 for(i=1; i<=n; i++){ //次数随便设置
49 x1=rand()%n+1; y1=rand()%n+1;
50 x2=rand()%n+1; y2=rand()%n+1;
51 tem=a[x1][y1]; a[x1][y1]=a[x2][y2]; a[x2][y2]=tem;
52 }
53 if (judge()==2*n+2)break;
54 }
55 for(i=1; i<=n; i++){
56 for(j=1; j<n; j++)
57 printf("%d ",a[i][j]);
58 printf("%d\n",a[i][n]);
59 }
60 }
61 return0;
62 }

 

 

zjut1005  做幻方

此题是求解奇幻方

记:关键是确定下一个数填的位置,规律是:1以后的每一个数只能填在它所在位置的下一行的下一列(记为A),如果A已经有数,就把下一个数填在当前这个数的上面(即与这个数同一列的上一个位置)

View Code
 1 #include<stdio.h>
2 #include<string.h>
3 #define nmax 101
4 int num[nmax][nmax];
5 int main() {
6 #ifndef ONLINE_JUDGE
7 freopen("data.in", "r", stdin);
8 #endif
9 int n, nn, i, j, k;
10 while (~scanf("%d", &n) && n) {
11 memset(num, 0, sizeof(num));
12 i = n - 1, j = n / 2, num[i][j] = 1;
13 for (k = 2, nn = n * n; k <= nn; k++) {
14 if (!num[(i + 1) % n][(j + 1) % n]) {
15 i = (i + 1) % n, j = (j + 1) % n;
16 } else {
17 i = (i - 1 + n) % n;
18 }
19 num[i][j] = k;
20 }
21 for (i = 0; i < n; i++) {
22 for (j = 0; j < n; j++) {
23 printf("%3d", num[i][j]);
24 }
25 printf("\n");
26 }
27 printf("\n");
28 }
29 return 0;
30 }

 

posted @ 2012-02-10 00:05  HUJJ  阅读(263)  评论(0编辑  收藏  举报