回 帖 发 新 帖 刷新版面

主题:n阶幻方程序

/**
* n阶幻方程序
* 完成者:meteor135
* 完成日期:2003.9.8
* 编译环境:VC6.0
*/
#include <iostream.h>
#include <iomanip.h>
#include <math.h>

void showFangzhen(int n);

int main()
{
    //输出10组幻方
    for(int n = 0; n < 10; n ++)
        showFangzhen(2*n+1);
    
    cout<<"Press enter to quit!";
    cin.get();

    return 0;
}

void showFangzhen(int n)
{
    if(!(n%2)) return;

    int i,j,**array;
    
    //为指针分配动态内存
    array=new int*[n];
    for(i=0; i<n; i++)
    {
        array[i] = new int[n];
    }
    
    //初始化数组
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            array[((n-1)/2+i-j+n)%n][(3*n-1+j-2*i)%n]=i*n+j+1;
            //or
            //array[(n+2*i-j)%n][((n-1)/2+n+j-i)%n]=i*n+j+1;
        }
    }

    //输出n阶幻方
    cout<<n<<"阶幻方:"<<endl;
    for(i=0; i<n; i++)
    {
        for(j=0;j<n;j++)
        {
            cout<<setw(int(log10(n*n))+2)<<array[i][j];
        }
        cout<<endl;
    }
    cout<<endl;
    
    //释放动态内存
    for(i=0; i<n; i++)
    {
        delete[] array[i];//原来是 delete array[i];
    }
    delete[] array;
}
//这是输出结果:
1阶幻方:
1

3阶幻方:
2 7 6
9 5 1
4 3 8

5阶幻方:
  9  3 22 16 15
  2 21 20 14  8
25 19 13  7  1
18 12  6  5 24
11 10  4 23 17

7阶幻方:
20 12  4 45 37 29 28
11  3 44 36 35 27 19
  2 43 42 34 26 18 10
49 41 33 25 17  9  1
40 32 24 16  8  7 48
31 23 15 14  6 47 39
22 21 13  5 46 38 30

9阶幻方:
35 25 15  5 76 66 56 46 45
24 14  4 75 65 55 54 44 34
13  3 74 64 63 53 43 33 23
  2 73 72 62 52 42 32 22 12
81 71 61 51 41 31 21 11  1
70 60 50 40 30 20 10  9 80
59 49 39 29 19 18  8 79 69
48 38 28 27 17  7 78 68 58
37 36 26 16  6 77 67 57 47

11阶幻方:
  54  42  30  18   6 115 103  91  79  67  66
  41  29  17   5 114 102  90  78  77  65  53
  28  16   4 113 101  89  88  76  64  52  40
  15   3 112 100  99  87  75  63  51  39  27
   2 111 110  98  86  74  62  50  38  26  14
121 109  97  85  73  61  49  37  25  13   1
108  96  84  72  60  48  36  24  12  11 120
  95  83  71  59  47  35  23  22  10 119 107
  82  70  58  46  34  33  21   9 118 106  94
  69  57  45  44  32  20   8 117 105  93  81
  56  55  43  31  19   7 116 104  92  80  68

13阶幻方:
  77  63  49  35  21   7 162 148 134 120 106  92  91
  62  48  34  20   6 161 147 133 119 105 104  90  76
  47  33  19   5 160 146 132 118 117 103  89  75  61
  32  18   4 159 145 131 130 116 102  88  74  60  46
  17   3 158 144 143 129 115 101  87  73  59  45  31
   2 157 156 142 128 114 100  86  72  58  44  30  16
169 155 141 127 113  99  85  71  57  43  29  15   1
154 140 126 112  98  84  70  56  42  28  14  13 168
139 125 111  97  83  69  55  41  27  26  12 167 153
124 110  96  82  68  54  40  39  25  11 166 152 138
109  95  81  67  53  52  38  24  10 165 151 137 123
  94  80  66  65  51  37  23   9 164 150 136 122 108
  79  78  64  50  36  22   8 163 149 135 121 107  93

15阶幻方:
104  88  72  56  40  24   8 217 201 185 169 153 137 121 120
  87  71  55  39  23   7 216 200 184 168 152 136 135 119 103
  70  54  38  22   6 215 199 183 167 151 150 134 118 102  86
  53  37  21   5 214 198 182 166 165 149 133 117 101  85  69
  36  20   4 213 197 181 180 164 148 132 116 100  84  68  52
  19   3 212 196 195 179 163 147 131 115  99  83  67  51  35
   2 211 210 194 178 162 146 130 114  98  82  66  50  34  18
225 209 193 177 161 145 129 113  97  81  65  49  33  17   1
208 192 176 160 144 128 112  96  80  64  48  32  16  15 224
191 175 159 143 127 111  95  79  63  47  31  30  14 223 207
174 158 142 126 110  94  78  62  46  45  29  13 222 206 190
157 141 125 109  93  77  61  60  44  28  12 221 205 189 173
140 124 108  92  76  75  59  43  27  11 220 204 188 172 156
123 107  91  90  74  58  42  26  10 219 203 187 171 155 139
106 105  89  73  57  41  25   9 218 202 186 170 154 138 122

17阶幻方:
135 117  99  81  63  45  27   9 280 262 244 226 208 190 172 154 153
116  98  80  62  44  26   8 279 261 243 225 207 189 171 170 152 134
  97  79  61  43  25   7 278 260 242 224 206 188 187 169 151 133 115
  78  60  42  24   6 277 259 241 223 205 204 186 168 150 132 114  96
  59  41  23   5 276 258 240 222 221 203 185 167 149 131 113  95  77
  40  22   4 275 257 239 238 220 202 184 166 148 130 112  94  76  58
  21   3 274 256 255 237 219 201 183 165 147 129 111  93  75  57  39
   2 273 272 254 236 218 200 182 164 146 128 110  92  74  56  38  20
289 271 253 235 217 199 181 163 145 127 109  91  73  55  37  19   1
270 252 234 216 198 180 162 144 126 108  90  72  54  36  18  17 288
251 233 215 197 179 161 143 125 107  89  71  53  35  34  16 287 269
232 214 196 178 160 142 124 106  88  70  52  51  33  15 286 268 250
213 195 177 159 141 123 105  87  69  68  50  32  14 285 267 249 231
194 176 158 140 122 104  86  85  67  49  31  13 284 266 248 230 212
175 157 139 121 103 102  84  66  48  30  12 283 265 247 229 211 193
156 138 120 119 101  83  65  47  29  11 282 264 246 228 210 192 174
137 136 118 100  82  64  46  28  10 281 263 245 227 209 191 173 155

19阶幻方:
170 150 130 110  90  70  50  30  10 351 331 311 291 271 251 231 211 191 190
149 129 109  89  69  49  29   9 350 330 310 290 270 250 230 210 209 189 169
128 108  88  68  48  28   8 349 329 309 289 269 249 229 228 208 188 168 148
107  87  67  47  27   7 348 328 308 288 268 248 247 227 207 187 167 147 127
  86  66  46  26   6 347 327 307 287 267 266 246 226 206 186 166 146 126 106
  65  45  25   5 346 326 306 286 285 265 245 225 205 185 165 145 125 105  85
  44  24   4 345 325 305 304 284 264 244 224 204 184 164 144 124 104  84  64
  23   3 344 324 323 303 283 263 243 223 203 183 163 143 123 103  83  63  43
   2 343 342 322 302 282 262 242 222 202 182 162 142 122 102  82  62  42  22
361 341 321 301 281 261 241 221 201 181 161 141 121 101  81  61  41  21   1
340 320 300 280 260 240 220 200 180 160 140 120 100  80  60  40  20  19 360
319 299 279 259 239 219 199 179 159 139 119  99  79  59  39  38  18 359 339
298 278 258 238 218 198 178 158 138 118  98  78  58  57  37  17 358 338 318
277 257 237 217 197 177 157 137 117  97  77  76  56  36  16 357 337 317 297
256 236 216 196 176 156 136 116  96  95  75  55  35  15 356 336 316 296 276
235 215 195 175 155 135 115 114  94  74  54  34  14 355 335 315 295 275 255
214 194 174 154 134 133 113  93  73  53  33  13 354 334 314 294 274 254 234
193 173 153 152 132 112  92  72  52  32  12 353 333 313 293 273 253 233 213
172 171 151 131 111  91  71  51  31  11 352 332 312 292 272 252 232 212 192

Press enter to quit!

回复列表 (共32个回复)

11 楼


奇数阶幻方解法,请阅读我的文章
http://www.kaoke.com/huanfang.htm

请问楼主,你的酸法
array[((n-1)/2+i-j+n)%n][(3*n-1+j-2*i)%n]=i*n+j+1;
是怎么来的,看来我的论文没有什么价值了,怎么这么相似。

我提供的vb算法


Sub huanfang2()
Dim i, j, x As Long

Text1.Text = ""
For j = 1 To N
For i = 1 To N
x = ((i + j + (N - 3) / 2) Mod N) * N + (i - j + (3 * N - 1) / 2) Mod N + 1
Text1.Text = Text1.Text + Space(6 - Len(Str(x))) + Str(x) + " "
Next i
Text1.Text = Text1.Text + vbCrLf
Next j

End Sub










12 楼

你的论文有没有获得大奖阿?如果获得了,证明我没有眼光,不知道你的论文的诞生日期是否比我的小程序早(当时我已注明是2003.9.8)。我倒是没觉得我的方法多么巧,而你的论文却称作《奇数阶幻方的巧妙构造》,而且你在论文中称:
===========================================================
奇数阶幻方构造完美终结版本!

本人在网上搜索很久,没有发现比我的方法还要简单的,特将我多年前发现的方法告诉大家!


本人在读初中时找到的解法:斜方格法
本人看了组合数学,介绍的方法有 斜排法和跳马法.绝对没有本人的方法方便,就是小学生也能掌握!

世界上不可能还有其他更方便的方法!
终极杀手非我pcgoer莫属!
===========================================================

实在是令我无言以对阿!!

13 楼

这些幻方太不够水平,有狠的把奇阶和偶阶综合在一起,并使用马步法排,斜排法太单一,没水准

14 楼

这些幻方太不够水平,有狠的把奇阶和偶阶综合在一起,并使用马步法排,斜排法太单一,没水准

15 楼

各位大虾帮忙看看,我这个程序怎么错了。。


/*
  幻方问题:
           给定一个自然数N,要将1~N^2(一到N的平方)填到N*N方阵中,怎样填使每一行,每
一列及对角线数字之和相等??
   若N为偶数,无解;若N为奇数,解法不一,其中一种解法为:
设N为5,:第一步:将数1填在第一行中间位置;
          第二步:目前自然数的左上方是下一个自然数:
                  A)。若目前自然数在第一行,但非最左列,则下一自然数在最后一行,
                             目前自然数的左一列;
                  B)。若目前自然数在第一行最左列,则下一自然数在目前数下侧;
                  C)。若目前自然数在最左侧,但并非在第一行,下一个数在上一行最右侧;
                  D)。方阵中该格已占有数,下一数移到目前数的同一列下一格;
15,8,1,24,17
16,14,7,5,23
22,20,13,6,4
3,21,19,12,10
9,2,25,18,11

*/
#include <iostream.h>
main()
{
    int n,i,j,k;
     int a[10][10];
    cout << "please input a number N=";
    cin >> n;
    while(n%2==0)  /*输入一个奇数N*/
         {cout << "please input once more N=" ;
         cin >> n;
          }

for(i=0;i<n;i++)
  for(j=0;j<n;j++)
    {if(i==0&&j==(n-1)/2) /*将数1填在第一行中间位置*/
       a[i][j]=1;
     else
       a[i][j]=0;      /*并将其它数设为零*/
     }

k=2;

while(k<=n*n)
{for(i=0;i<n;i++)
    {for(j=0;j<n;j++)
      {if(a[i][j]==0)
           { if(j!=0&&i==0)  a[0][n-1]=k;
             else if(i==0&&j==0)    a[i+1][j]=k;
             else if(i!=0&&j==0)     a[i-1][j]=k;
             else            a[i-1][j-1]=k;
           }
        else  a[i+1][j]=k;
       k=k+1;
      }
    }
  }

for(i=0;i<n;i++)
   {cout << endl;
     for(j=0;j<n;j++)
     cout << a[i][j];
   }
getch();
}

16 楼

怎么没人回啊?斑竹哪里去了?

17 楼

以下是我的改进程序,还是有错,请帮忙看看
#include <stdio.h>
//#define MAX=10

main()
{
    int i,j,k,n;
    int a[10][10];

    //input an odd num
    printf("Please input an odd number n=");
    scanf("%d",&n);
    while(n%2==0)
    {
        printf("An odd number please! n=");
        scanf("%d",&n);
    }

    //set a[0][(n-1)/2]=1,others 0
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            {if(i==0&&j==(n-1)/2)    a[i][j]=1;
            else    a[i][j]=0;}

    //print the array
    for(i=0;i<n;i++)
        {{for(j=0;j<n;j++)
            printf("%2d ",a[i][j]);}
        printf("\n");}
    printf("\n");

    //main circle
    k=2;
    while(k<=n*n)
    {
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
            if(a[i][j]!=0)
            {
                if(i==0&&j==0&&a[i+1][j]==0)    a[i+1][j]=k++;
                else if(i==0&&j!=0&&a[n-1][j-1]==0)    a[n-1][j-1]=k++;
                else if(i!=0&&j==0&&a[i-1][n-1]==0)    a[i-1][n-1]=k++;
                else if(i!=0&&j!=0)
                    {if(a[i-1][j-1]==0)    a[i-1][j-1]=k++;
                    else
                        {if(a[i+1][j]==0) a[i+1][j]=k++;}
                    }
            }
    //print the array
    /*for(i=0;i<n;i++)
        {{for(j=0;j<n;j++)
            printf("%2d ",a[i][j]);}
        printf("\n");}
    printf("\n");*/
    }
    //print the array
    for(i=0;i<n;i++)
        {{for(j=0;j<n;j++)
            printf("%2d ",a[i][j]);}
        printf("\n");}
    printf("\n");

    //getchar
    getchar();
    getchar();
}

18 楼

/*WIN_TC编写的穿心对调法求n阶幻方*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_INDEX   100

void swap(int *a,int *b)
{
    int t;
    t=*a;
    *a=*b;
    *b=t;
}

/*快速排序算法*/
void QuickSort(int a[], int l, int r)

{
    int i=l; /*从左至右的游标*/
    int j=r + 1; /*从右到左的游标*/
    int pivot=a[l];
    if (l >= r) return;
     /*把左侧>= pivot的元素与右侧<= pivot 的元素进行交换*/
    while (1)
        {
            do
            {/*在左侧寻找>= pivot 的元素*/
                i = i + 1;
            } while (a[i] < pivot);
            do
            {/*在右侧寻找<= pivot 的元素*/
                j = j - 1;
            } while (a[j] > pivot);
            if (i >= j) break; /*未发现交换对象*/
            swap(&a[i],&a[j]);
        }

    /*设置p i v o t*/
    a[l] = a[j];
    a[j] = pivot;
    QuickSort(a, l, j-1); /*对左段排序*/
    QuickSort(a, j+1, r); /*对右段排序*/
}


void Huanf(int Array[][MAX_INDEX],int n)
{
    int i,j;
    int a,b,m;
    int tempArray1[MAX_INDEX];
    int tempArray2[MAX_INDEX];
    a=n/2;
    b=a+1;
    m=n%4;
    switch(m)
    {
    case 0:
    case 2:
        /*穿心对调*/
        for(i=0;i<n;i++)
        for(j=0;j<n/2;j++)
        {
            if(i<n/2)
            {
                if(i%2==1&&Array[i][j]%2==0)/*偶行换偶*/
                {
                    swap(&Array[i][j],&Array[n-1-i][n-1-j]);
                }
                else if(i%2==0&&Array[i][j]%2==1)/*奇行换奇*/
                {
                    swap(&Array[i][j],&Array[n-1-i][n-1-j]);
                }
            }
            else
            {
                if(i%2==1&&Array[i][j]%2==1)/*偶行换奇*/
                {
                    swap(&Array[i][j],&Array[n-1-i][n-1-j]);
                }
                else if(i%2==0&&Array[i][j]%2==0)/*奇行换偶*/
                {
                    swap(&Array[i][j],&Array[n-1-i][n-1-j]);
                }  
            }

        }
        /*End穿心对调*/
        if(m==2)
        {
            for(i=0;i<n/2;i++)
            {
                if((i!=0)&&(i!=a-1)&&(i!=b-1)&&(i!=n-1))
                {
                    swap(&Array[i][a-1],&Array[n-1-i][a-1]);
                    swap(&Array[b-1][i],&Array[b-1][n-1-i]);
                }
            }
            swap(&Array[0][a-1],&Array[0][b-1]);
            swap(&Array[a-1][0],&Array[b-1][0]);
            swap(&Array[2][0],&Array[2][n-1]);
            swap(&Array[0][2],&Array[n-1][2]);  
        }
        break;
    case 1:
    case 3:
        /*穿心对调*/
        for(i=0;i<n;i++)
            for(j=0;j<n/2;j++)
            {
                if(i<n/2)
                {
                    if(i%2==1&&Array[i][j]%2==0) /*偶行换偶*/
                    {
                        swap(&Array[i][j],&Array[n-1-i][n-1-j]);
                    }
                    else if(i%2==0&&Array[i][j]%2==0)/*奇行换奇*/
                    {
                        swap(&Array[i][j],&Array[n-1-i][n-1-j]);
                    }
                }
                else if(i>n/2)
                {
                    if(i%2==1&&Array[i][j]%2==0)/*偶行换偶*/
                    {
                        swap(&Array[i][j],&Array[n-1-i][n-1-j]);
                    }
                    else if(i%2==0&&Array[i][j]%2==0)/*奇行换奇*/
                    {
                        swap(&Array[i][j],&Array[n-1-i][n-1-j]);
                    }
                }
            }
        /*End穿心对调*/
        /*重排米字*/
        for(i=0;i<n;i++)
        {
            tempArray1[i]=Array[i][i];
            tempArray2[i]=Array[a][i];
        }

        QuickSort(tempArray1,0,n-1);
        QuickSort(tempArray2,0,n-1);
        for(i=0;i<n;i++)
        {
            Array[i][i]=tempArray2[i];
            Array[a][i]=tempArray1[i];
        }
        for(i=0;i<n;i++)
        {
            tempArray1[i]=Array[i][n-1-i];
            tempArray2[i]=Array[i][a];
        }
        QuickSort(tempArray1,0,n-1);
        QuickSort(tempArray2,0,n-1);
        for(i=0;i<n;i++)
        {
            Array[i][n-1-i]=tempArray2[i];
            Array[i][a]=tempArray1[i];
        }
        /*End重排米字*/

        if(m==3)
        {
             for(i=0;i<n/2;i++)
            {
                if((i!=a-1)&&(i!=b-1)&&(i!=a+1))
                {
                    swap(&Array[i][a-1],&Array[n-1-i][a-1]);
                    swap(&Array[a-1][i],&Array[a-1][n-1-i]);
                }
            }
            swap(&Array[a-1][a-1],&Array[a+1][a+1]);
            swap(&Array[a-1][b-1],&Array[a+1][b-1]);   
        }
        break;
    default:
        break;
    }
    return;
}


int main()
{
   int Ne[MAX_INDEX][MAX_INDEX];
   int i,j,n;

   printf("Please Input N:");
   scanf("%d",&n);
   printf("\n");
   while(n!=0&&n<=MAX_INDEX)
   {
        /*数组赋初值*/
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
                Ne[i][j]=i*n+(j+1);

        Huanf(Ne,n);

        for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {
            printf("%-4d",Ne[i][j]);
            if(j==n-1)
                printf("\n\n");
        }
        printf("\n\n");
        printf("Please Input N:");
        scanf("%d",&n);
        printf("\n");
    }
    printf("N is invalid!");
   getch();
}

19 楼

#include <iostream.h>
#include <iomanip.h>
#include <math.h>

void showFangzhen(int n);

int main()
{
    //输出10组幻方
    for(int n = 0; n < 10; n++)
        showFangzhen(n+1);                  //将里面的2*n改为n//
    
    cout<<"Press enter to quit!";
    cin.get();

    return 0;
}

void showFangzhen(int n)
{
    /*if(!(n%2)) return;*/                     //将该语句去掉//

    int i,j,**array;
    
    //为指针分配动态内存
    array=new int*[n];
    for(i=0; i<n; i++)
    {
        array[i] = new int[n];
    }
    
    //初始化数组
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            array[((n-1)/2+i-j+n)%n][(3*n-1+j-2*i)%n]=i*n+j+1;
            //or
            //array[(n+2*i-j)%n][((n-1)/2+n+j-i)%n]=i*n+j+1;
        }
    }

    //输出n阶幻方
    cout<<n<<"阶幻方:"<<endl;
    for(i=0; i<n; i++)
    {
        for(j=0;j<n;j++)
        {
            cout<<setw(int(log10(n*n))+2)<<array[i][j];
        }
        cout<<endl;
    }
    cout<<endl;
    
    //释放动态内存
    for(i=0; i<n; i++)
    {
        delete[] array[i];//原来是 delete array[i];
    }
    delete[] array;
}
这样就可以输出偶数的幻方程序了

20 楼

#include <iostream.h>
#include <iomanip.h>
#include <math.h>

void showFangzhen(int n);

int main()
{
    //输出10组幻方
    for(int n = 0; n < 10; n++)
        showFangzhen(n+1);//将里面的2*n改为n//
    
    cout<<"Press enter to quit!";
    cin.get();

    return 0;
}

void showFangzhen(int n)
{
    /*if(!(n%2)) return;*/       //将该语句去掉//

    int i,j,**array;
    
    //为指针分配动态内存
    array=new int*[n];
    for(i=0; i<n; i++)
    {
        array[i] = new int[n];
    }
    
    //初始化数组
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            array[((n-1)/2+i-j+n)%n][(3*n-1+j-2*i)%n]=i*n+j+1;
            //or
            //array[(n+2*i-j)%n][((n-1)/2+n+j-i)%n]=i*n+j+1;
        }
    }

    //输出n阶幻方
    cout<<n<<"阶幻方:"<<endl;
    for(i=0; i<n; i++)
    {
        for(j=0;j<n;j++)
        {
            cout<<setw(int(log10(n*n))+2)<<array[i][j];
        }
        cout<<endl;
    }
    cout<<endl;
    
    //释放动态内存
    for(i=0; i<n; i++)
    {
        delete[] array[i];//原来是 delete array[i];
    }
    delete[] array;
}
这样就可以了

我来回复

您尚未登录,请登录后再回复。点此登录或注册