c-请教一下魔方阵的问题。。

问题描述

请教一下魔方阵的问题。。

(每一行每一列以及对角线之和都相等的方阵)
要求输出1--n*n的魔方阵
(。。用的方法不好。。但是不知道哪里错了>_<)

#include
#include
int main()
{
int m[15][15],k,n,i,j;
for(n=2;n%2==0;)
{printf("enter your number:");
scanf("%d",&n);}
for(k=1,i=1,j=(n+1)/2;k<=n;k++)
{
m[i][j]=k;
if(i==1)
{
if(j==n)
{
l=m[n][1];
if(l==0) {m[n][1]=k+1;i=n;j=1;}
else {m[i+1][j]=k+1;i=i+1;}
}
else {
l=m[n][j+1];
if(l==0) {m[n][j+1]=k+1;i=n;j=j+1;}
else {m[i+1][j]=k+1;i=i+1;}
}
}
else
{
if(j==n)
{
l=m[i-1][1];
if(l==0) {m[i-1][1]=k+1;i=i-1;j=1;}
else {m[i+1][j]=k+1;i=i+1;}
}
}
l=m[i-1][j+1];
if(l==0) {m[i-1][j+1]=k+1;i=i-1;j=j+1;}
else {m[i+1][j]=k+1;i=i+1;}
}

for(i=1;i<=n;i++)
{ for(j=1;j<=n;j++)
printf("%d ",m[i][j]);
printf("
");
}

return 0;}

解决方案

 // app2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include<stdio.h>
#include<math.h>
#define MAX 30
int a[MAX][MAX];    // 幻方矩阵
int n,s;    // n:阶数,s:幻方数
int x,y;
int i,j,k;
int total,m;
int ox,oy;
void main()
{
    void odd(int m, int index);
    void singleEven();
    void FourXFour();
    void doubleEven();

    do
    {
        printf("Please input n(3<=n[<=17]):	");    // 屏幕可显示的最大阶数为17
        scanf("%d",&n);
        if(n<3) continue;   // 幻方最小阶数
        s=n*(pow(n,2)+1)/2; // 幻方数
        printf("s=%d
",s);
        if(n%2==1){
            // 奇阶幻方
            ox=oy=0;
            odd(n,0);   // 从1开始填写n阶幻方
        }
        else if(n%4==0)
        {
            // 双偶阶幻方
            doubleEven();

        }
        else if(n%2==0)
        {
            // 单偶阶幻方
            singleEven();

        }
        // 输出制作好的n阶幻方
        for(i=0;i<n;i++)
        {
            s=0;
            for(j=0;j<n;j++)
                s+=a[i][j],printf("%4d",a[i][j]);
            printf("	=%d
",s);
        }
        fflush(stdin);  // 清除多余或无效的输入
    }while(1);
}
/* 奇数阶幻方
最经典的填法是罗伯特法(楼梯法),填写方法是这样:
把1(或最小的数)放在第一行正中;按以下规律排列剩下的n×n-1个数:
(1)每一个数放在前一个数的右上一格;
(2)如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;
(3)如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;
(4)如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在前一个数的下一行同一列的格内;
(5)如果这个数所要放的格已经有数填入,处理方法同(4)。
这种写法总是先向“右上”的方向,象是在爬楼梯。
三阶幻方:
   8   1   6
   3   5   7
   4   9   2    */
// 解奇阶幻方的通用模块
// m 为阶数
// index 为起始标识
void odd(int m, int index)
{
    x=m/2;
    y=0;
    for(i=index+1;i<=index+pow(m,2);i++)
    {
        a[oy+y][ox+x]=i;
        if(i%m==0) y++;
        else x++,y--;
        // else x++,y+=2; Hourse法
        x=(x%m+m)%m;
        y=(y%m+m)%m;
    }
}
/* 单偶阶幻方
n为偶数,且不能被4整除 (n=6,10,14,18,22……;n=4k+2,k=1,2,3,4,5……)
以n=10为例。这时,k=2
(1) 把方阵分为A,B,C,D四个象限,这样每一个象限肯定是奇数阶。
用楼梯法,依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数。
6阶幻方第一步:
   8   1   6 | 26  19  24
   3   5   7 | 21  23  25
   4   9   2 | 22  27  20
-------------------------
  35  28  33 | 17  10  15
  30  32  34 | 12  14  16
  31  36  29 | 13  18  11
(2) 在A象限的中间行、中间格开始,按自左向右的方向,标出k格。
A象限的其它行则标出最左边的k格。
将这些格,和C象限相对位置上的数,互换位置。
6阶幻方第二步:
  35*  1   6 | 26  19  24
   3  32*  7 | 21  23  25
  31*  9   2 | 22  27  20
-------------------------
   8* 28  33 | 17  10  15
  30   5* 34 | 12  14  16
   4* 36  29 | 13  18  11
(3) 在B象限任一行的中间格,自右向左,标出k-1列。
(注:6阶幻方由于k-1=0,所以不用再作B、D象限的数据交换)
将B象限标出的这些数,和D象限相对位置上的数进行交换,就形成幻方。
6阶幻方:
  35   1   6 | 26  19* 24
   3  32   7 | 21  23* 25
  31   9   2 | 22  27* 20
-------------------------
   8  28  33 | 17  10* 15
  30   5  34 | 12  14* 16
   4  36  29 | 13  18* 11   */
void singleEven()
{
    int temp;
    // 步骤一
    // A象限
    ox=oy=0;
    odd(n/2,pow(n/2,2)*0);
    // D象限
    ox=oy=n/2;
    odd(n/2,pow(n/2,2)*1);
    // B象限
    ox=n/2,oy=0;
    odd(n/2,pow(n/2,2)*2);
    // C象限
    ox=0,oy=n/2;
    odd(n/2,pow(n/2,2)*3);
    // 对已经按ADBC象限以奇阶方式填充的幻方做处理
    m=(n-2)/4;
    for(i=0;i<n/2;i++)
    {
        // 步骤二
        for(j=0;j<m;j++)
        {
            k=(i==n/4)?n/4+j:j;
            temp=a[i][k];
            a[i][k]=a[i+n/2][k];
            a[i+n/2][k]=temp;
        }
        // 步骤三
        for(j=0;j<m-1;j++)
        {
            k=n/2+n/4+j;
            temp=a[i][k];
            a[i][k]=a[i+n/2][k];
            a[i+n/2][k]=temp;
        }
    }
}
/* 双偶阶幻方
n为偶数,且能被4整除 (n=4,8,12,16,20……;n=4k,k=1,2,3,4,5……)
互补:如果两个数字的和,等于幻方最大数和最小数的和,即 n*n+1,称为互补。*/
/* 四阶幻方
将数字从左到右、从上到下按顺序填写:
   1   2   3   4
   5   6   7   8
   9  10  11  12
  13  14  15  16
将对角线上的数字,换成与它互补的数字。
这里,n×n+1 = 4×4+1 = 17;
把1换成17-1 = 16;
把6换成17-6 = 11;
把11换成17-11 = 6;
把16换成17-16 = 1;
……
换完后就是一个四阶幻方。
  16*  2   3  13*
   5  11* 10*  8
   9   7*  6* 12
   4* 14  15   1* */
void FourXFour()
{
    // 对已填写数字的4阶幻方进行对角线互补替换
    for(i=0;i<4;i++)
    {
        a[oy+i][ox+i]=total-a[oy+i][ox+i];
        a[oy+i][ox+(4-i-1)]=total-a[oy+i][ox+(4-i-1)];
    }
}
/* 对于n=4k阶幻方,我们先把数字按顺序填写。
   1   2   3   4   5   6   7   8
   9  10  11  12  13  14  15  16
  17  18  19  20  21  22  23  24
  25  26  27  28  29  30  31  32
  33  34  35  36  37  38  39  40
  41  42  43  44  45  46  47  48
  49  50  51  52  53  54  55  56
  57  58  59  60  61  62  63  64
写好后,按4*4把它划分成k*k个方阵。
因为n是4的倍数,一定能用4*4的小方阵分割。
   1   2   3   4 |  5   6   7   8
   9  10  11  12 | 13  14  15  16
  17  18  19  20 | 21  22  23  24
  25  26  27  28 | 29  30  31  32
---------------------------------
  33  34  35  36 | 37  38  39  40
  41  42  43  44 | 45  46  47  48
  49  50  51  52 | 53  54  55  56
  57  58  59  60 | 61  62  63  64
然后把每个小方阵的对角线上的数字换成互补的数字,就构成幻方。
  64*  2   3  61*| 60*  6   7  57*
   9  55* 54* 12 | 13  51* 50* 16
  17  47* 46* 20 | 21  43* 42* 24
  40* 26  27  37*| 36* 30  31  33*
---------------------------------
  32* 34  35  29*| 28* 38  39  25*
  41  23* 22* 44 | 45  19* 18* 48
  49  15* 14* 52 | 53  11* 10* 56
   8* 58  59   5*|  4* 62  63   1* */
void doubleEven()
{
    // 填写数字
    x=y=0;
    for(i=1;i<=pow(n,2);i++)
    {
        a[y][x]=i;
        if(i%n==0) x=0,y++;
        else x++;
    }
    total=1+pow(n,2);   // 最大数和最小数的和
    // 以 4x4 大小分割幻方
    m=n/4;
    x=y=0;
    ox=oy=0;
    for(k=1;k<=pow(m,2);k++)
    {
        // 对每个 4x4 幻方做对角互补替换
        FourXFour();
        if(k%m==0) ox=0,oy+=4;
        else ox=k%m*4;  // 转移到下一个 4x4 幻方
    }
}

Please input n(3<=n[<=17]): 3
s=15
8 1 6 =15
3 5 7 =15
4 9 2 =15
Please input n(3<=n[<=17]): 5
s=65
17 24 1 8 15 =65
23 5 7 14 16 =65
4 6 13 20 22 =65
10 12 19 21 3 =65
11 18 25 2 9 =65
Please input n(3<=n[<=17]):

源程序略有点问题,我顺手修改了
出处
http://blog.csdn.net/cmutoo/article/details/5487157

解决方案二:

岂止是方法不好,程序根本就是错的

enter your number:3
-858993460 1 -858993460
-858993460 2 -858993460
-858993460 2 -858993460
Press any key to continue

解决方案三:

奇数阶魔方阵问题
魔方问题

时间: 2025-01-27 04:10:37

c-请教一下魔方阵的问题。。的相关文章

生成魔方阵(周记05-03)

最近加紧学C#,同时又想再看看算法.谁要咱们在科研口,就是一个自己的时间多,当然money也就少些了. 书买了不少,什么<21天学通C#>.<C#Primer>还有<Microsoft .Net框架程序设计(修订版)>.当然这些书的选择是本人看了不少书评后才买的,看了看都是不错的选择,好书! 书虽好但也要人用心来看啊,本人利用业余时间基本已浏览一遍,更细的知识点就要在以后的学习中好好掌握了. 说到这里,说出来你死都不会相信我在单位还是个小头,平日里受尽老老少少.上上下下

C语言实现奇数阶魔方阵的方法_C 语言

本文实例讲述了C语言实现奇数阶魔方阵的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: #include "stdio.h" #include "string.h" #include "stdlib.h" #define N 5 void main(){ int a[N][N]={0}; int i,j; int k; i = 0; j = N/2; a[0][j]=1; for(k = 2; k <= N*N; k++

linux下c语言魔方阵程序

#include<stdio.h> #include<stdlib.h> int main() { int a[31][31], i, j, m, n, p = 0; while(p == 0) { system("clear"); printf("请输入不大于30的奇数:"); scanf("%d",&m); if(m != 0 && m <= 30 && m % 2 !=

设计-求解啊 ............ 老师要求C++解

问题描述 求解啊 ............ 老师要求C++解 二.编程题(需给出源代码和程序运行截图) 1. 设计程序实现n*n魔方矩阵(n为奇数)的输出. n*n魔方矩阵就是指每一行.每一列以及两个对角线上的n个自然数的和都相等的方阵.如3*3魔方矩阵为: 8 1 6 3 5 7 4 9 2 矩阵内填写的数值为1-n*n的自然数.使用已学过的数组相关知识编写程序实现任意n*n魔方矩阵(n为奇数)的构造并显示出最终矩阵的结果. 输入输出要求: (1) n的值由用户指定 (2) 输出时按照矩阵的形

如何求n阶方阵中各条反斜线上的元素之和4*4

#include<stdio.h> void main() { //其中第一条斜线是00 - 11 - 22 -33 第二条10 - 21 - 32 int arr2[4][4] = { 00, 01, 02, 03, 10 , 11, 12, 13, 20 , 21, 22, 23, 30, 31, 32, 33,}; int i, j; int sum = 0; int index = 0; for (int i = 0; i < 4; i++) { for (int j = 0;

C++ 算法大全

第3章 控制语句  /* 1.打印出所有的"水仙花数".所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身.例如,153是一水仙花数,因为153 = 13 + 53 + 33. */ #include<iostream.h> void main() { int i, a=0, b=0, c=0; for(i=100;i<1000;i++) { a=i%10; b=i/10%10; c=i/100%10; if(a*a*a+b*b*b+c*

《MATLAB图像处理375例》——1.5 数组与矩阵

1.5 数组与矩阵 MATLAB图像处理375例 数值数组(简称为数组)是MATLAB中最重要的一种内建数据类型,是MATLAB软件定义的运算规则,其目的是为了数据管理方便.操作简单.指令形式自然和执行计算的有效. 1.5.1 数组的创建与操作 行数组:n个元素排成一行,又称为行向量. 列数组:m个元素排成一列,又称为列向量. 用方括号[ ]创建一维数组就是将整个数组放在方括号里,行数组元素用空格或逗号分隔,列数组元素用分号分隔,标点符号一定要在英文状态下输入. [例1-3]创建数组示例. cl

【算法导论】幻方算法

        说起幻方,大家应该在小学时候就已经接触过了,最简单的就是九宫格,射雕英雄传中的那段至今还记得:戴九履一,左三右七,二四为肩,六八为足.下面我们就来看看这个有趣的问题.         幻方可以分为:奇数阶幻方.双偶阶幻方.单偶阶幻方. 奇数阶幻方        上面所说的九宫格就是典型的奇数阶幻方,奇数阶幻方值得是阶数为奇数的幻方.其最经典的填法是罗伯法.首先 把1(或最小的数)放在第一行正中:按以下规律排列剩下的(n×n-1)个数,具体步骤为: (1)每一个数放在前一个数的右上

自定义控件-请教,展开的魔方,这是用什么控件什么view做的?

问题描述 请教,展开的魔方,这是用什么控件什么view做的? 下面一行点击用来选中颜色,触摸中间的大方块用来填充,右上方动态显示大致效果.怎么定义的啊? 解决方案 http://www.cnblogs.com/wendingding/p/3771047.html 解决方案二: 截屏也可以实现的.截取视窗你动态选配的地方就可以了. 解决方案三: 下面的选择框可以使用viewpage来实现