zoukankan      html  css  js  c++  java
  • 魔方阵 奇数偶数都成立

    《C程序设计(第四版)》 谭浩强的,第六章 第7题 有一个输出 魔方阵的题,相信困惑了不少人,下面本文给予大家完整的解答。

    所谓魔方阵即1-N*N个数排成一个n阶矩阵,矩阵特点:每一行,每一列,对角线之和都等于相同的值。

    下面根据资料总结得到:

    1):奇数的魔方阵:

    其数字排列规则如下:

        1)将1填入第一行中间;

      2)将每个数填在前一个数的右上方。

      3)若该位置超出最上行,则改填在最下行的对应位置;

      4)若该位置超出最右列,则该填在最左列的对应行位置;

      5)若某元素填在第一行最右列,下一个数填在该数同列的下一行;

      6)若某数已找到了填写位置,但其已填了其他数据,则这个数应填在应该填的位置的同列的下一行位置。

     

    自己的代码如下:

    #include<stdio.h> //此为求奇魔方阵的方法
    #include<string.h>
    int main()
    {
    int a[100][100],i,j,n,k,x,y;
    printf("Enter n:\n");
    while(scanf("%d",&n)!=EOF&&(n%2==1))
    {
    memset(a,0,sizeof(a));//将原始数组全部清0;必须清零
    i=0;
    j=n/2;
    a[i][j]=1; //第一条
    for(k=2;k<=n*n;k++)
    {
    x=i; //x,y记录原来一个数的坐标
    y=j;
    i--;
    j++;
    if(i<0)i=n-1; //第二条
    if(j>n-1)j=0; //第三条
    if(a[0][n-1]!=0)//第四条 此条可以省略
    {
    a[1][n-1]=a[0][n-1]+1;
    }
    if(a[i][j]!=0)// 第五条
    {
    i=x+1;
    j=y;
    }
    a[i][j]=k;

    }

    for(i=0;i<n;i++) //输出此数组
    {
    for(j=0;j<n;j++)
    printf("%4d",a[i][j]);
    putchar('\n');
    }
    printf("Enter n:\n");
    }
    return 0;
    }

     

    2):双偶数魔方阵:

    所谓双偶数即2*(2m)的数据,即4的整数倍,期排列特点如下:

    1:把魔方阵分为上下左右4个n/2*n/2的小的方阵,左上角和右下角的n/2*n/2的小矩阵

    2:偶行偶列,奇行奇列赋值为0,其余赋值为1;右上角和左上角的n/2*n/2的小矩阵,偶行奇列,奇行偶列赋值为0,其余赋值为1。

    3:从魔方阵由左到右,由上到下开始赋值,赋值为从n*n到1,若遇到原来填入方阵中的0,则跳过此格;

    4:从魔方阵由左到右,由上到下开始赋值,赋值为从1到n*n,若遇到原来填入方阵中的1,则跳过此格;

    5:填完数据后则完成 双偶数魔方阵;

    我的代码如下:

    #include<stdio.h>//双偶数的魔方阵 即4*m阶 (m=1,2,3...)
    #include<string.h>
    int main()
    {
    int n,a[100][100],i,j,k;
    while(scanf("%d",&n)!=EOF&&(n%4==0)&&n>0)
    {
    memset(a,0,sizeof(a));
    for(i=0;i<n;i++)
    for(j=0;j<n;j++)
    {
    if(i<n/2&&j<n/2||i>=n/2&&j>=n/2) //分别填入 0和1
    if(i%2==0&&j%2==1||i%2==1&&j%2==0)
    a[i][j]=1;
    if(i>=n/2&&j<n/2||i<n/2&&j>=n/2)
    if(i%2==0&&j%2==0||i%2==1&&j%2==1)
    a[i][j]=1;
    }
    k=n*n;
    for(i=0;i<n;i++) //填入n*n到1
    for(j=0;j<n;j++)
    {
    if(a[i][j]==1)a[i][j]=k;
    k--;
    }
    k=1;
    for(i=0;i<n;i++)//填入1到n*n 并输出魔方阵
    {
    for(j=0;j<n;j++)
    {
    if(a[i][j]==0)a[i][j]=k;
    k++;
    printf("%4d",a[i][j]);
    }
    putchar('\n');
    }
    }
    }


    3):单偶数魔方阵

    所谓单偶数,即n=2*(2m+1)的数据,其数字排列特点如下:

    1:将矩阵分为4个区,A、B、C、D区,其相对位置如下:

    A C
    D B


    2:先把数字1到(n/2)*(n/2)按照奇数魔方阵的方法填入A中,然后把其每一个数据分别加上(n/2)*(n/2)填入到B中,再把B中的数据加上(n/2)*(n/2)填入到C中,再把C中的数据加上(n/2)*(n/2)填入到D中;

    3:交换数字

    需要交换的数字的规则:

    1: 右边两个小方阵中大于(m+2)的列中所有的数字
    2
    : 左边两个小方阵中(m+1,m+1)这一个方格的数字
    3
    : 左边两个小方阵中除(m+1,1)格位之外,小于m+1的列中的所有数字

    其中n=2*(2m+1);即m=(n-2)/4;

    比如说n=6,即m=1这个例子;

    先把这些数字做标记:如图

    只需要标记A区和C区数字即可,然后A区和D区数字对应交换,

    C区和B区数字对应进行交换,此例C区没有交换数字:

    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

    然后交换即得到单偶数魔方阵:如下图:

    35 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

    代码如下:

    #include<stdio.h>  // A  C      A、B、C、D四块的相对位置
    #include<string.h> // D B
    #define M 100
    void output(int a[][M],int n)
    {
    int i,j;
    for(i=0;i<n;i++)
    {
    for(j=0;j<n;j++)
    printf("%4d",a[i][j]);
    printf("\n");
    }
    }
    int main()
    {
    int a[100][100],i,j,k,x,y,n,m,t;
    printf("请输入单偶数n:\n");
    while(scanf("%d",&n)!=EOF)
    {
    memset(a,0,sizeof(a));

    //输入A矩阵
    a[0][n/2/2]=1;
    i=0;
    j=n/2/2;
    for(k=2;k<=(n/2*n/2);k++)
    {
    x=i;
    y=j;
    i--;
    j++;
    if(i<0)i=n/2-1;
    if(j>n/2-1)j=0;
    if(a[i][j]!=0)
    {
    i=x+1;
    j=y;
    }
    a[i][j]=k;
    }
    //输入B矩阵
    for(i=n/2;i<n;i++)
    for(j=n/2;j<n;j++)
    {
    a[i][j]=a[i-n/2][j-n/2]+(n/2)*(n/2);
    }
    //C...
    for(i=0;i<n/2;i++)
    for(j=n/2;j<n;j++)
    {
    a[i][j]=a[i+n/2][j]+(n/2)*(n/2);
    }
    //D...
    for(i=n/2;i<n;i++)
    for(j=0;j<n/2;j++)
    {
    a[i][j]=a[i-n/2][j+n/2]+(n/2)*(n/2);
    }


    //交换数字
    //A和D换 因为n=2*(2m+1),所以m=(n-2)/4

    //步骤1: 交换第(m+1,m+1)格
    m=(n-2)/4;
    t=a[m][m];
    a[m][m]=a[m+n/2][m];
    a[m+n/2][m]=t;
    //2:交换除了(m+1,1)格以外的小于m+1的列
    for(i=0;i<n/2;i++)
    for(j=0;j<n/2;j++)
    {
    if(j<m)
    {
                   if(i==m&&j==0)continue;
    t=a[i][j];
    a[i][j]=a[i+n/2][j];
    a[i+n/2][j]=t;
    }
    }
    //C和B的交换

    for(i=0;i<n/2;i++)
    for(j=n/2;j<n;j++)
    {
    if(j>n/2+m+1)
    {
    t=a[i][j];
    a[i][j]=a[i+n/2][j];
    a[i+n/2][j]=t;
    }
    }

    output(a,n); //输出魔方阵
    printf("请输入单偶数n:\n");
    }

    return 0;
    }

    好了,这就是1--n阶的魔方阵,当然魔方阵的排列规则有很多,还可以构造魔方阵,只要记住其中一种方法就可以了,若要看整合的代码,并带有检测是否为魔方阵的环节,请看下篇魔方阵(2),这就是魔方阵的全面解答,与大家分享,此文若有有不足之处或错误请指正;

  • 相关阅读:
    Delphi XE2 update4 很快就要来了
    树型菜单表的合并。
    VS宏 之 选中解决方案中的文件
    Mvc,接收复杂对象。
    SQL 2008 CLR开发自定义聚合函数
    数据库主键按业务规则生成的解决方案。
    一些独特的语言思考
    vs环境设置
    SqlServer 2005+ 开发问题
    记录 VS 中的生成时间
  • 原文地址:https://www.cnblogs.com/hsqdboke/p/2385454.html
Copyright © 2011-2022 走看看