| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1927 人关注过本帖, 1 人收藏
标题:每日一题!NO.3(适合新手做练习)-幻方问题(已经给出答案!)
只看楼主 加入收藏
啊C
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:84
专家分:177
注 册:2010-6-24
结帖率:91.67%
收藏(1)
已结贴  问题点数:1 回复次数:23 
每日一题!NO.3(适合新手做练习)-幻方问题(已经给出答案!)
简单问题:
所谓幻方,就是一个N行N列的正方型,当N为奇数时,称为奇数阶幻方。共有N的平方个格子,将1.2.3.....。N的平方这些数字方到这些格子里,使其每行的和,每列的和及两条对角线的和都是一个相同的数。试编程由键盘输入一个奇数N,输出一个N阶幻方。
请写上注释!
答案明日公布;
图片附件: 游客没有浏览图片的权限,请 登录注册

算法下面的朋友都给出来,其实其他的七种算法可以让已经得到的表格,旋转和对折后再分析算法,但决不是左上或右上这么少,还可以是左下,右下,当然第一个数字的位置也可以变的,可以分析哈,当练习分析能力。
给数的数据,由于排版问题,输入数字大了,就会自动移动到下一行会迫害排版,所以,好输入3以上的输出结果还好自己排版才能更好的观看输出结果!
程序代码:
#include<stdio.h>
#include<stdlib.h>
void main()
{
    int i=0,j,k=1,iold,jold,n,nn[50][50]={0};//定义自变量
    printf("请输入奇数\n");
    scanf("%d",&n);
    if(n%2!=1)//验证输入是不是奇数
    {
        printf("输入的不是奇数\n");
        getchar();
        exit(0);
    }
    j=n/2;
    for(;k<=n*n;k++)//循环添加数字,每下一个数在原来的基础上加1“k++”
    {
        nn[i][j]=k;//填数字在表格里
        iold=i;//记录这次添数字表格的坐标
        jold=j;//
        i=i-1;//向右上移动一格
        j=1+j;//
        if(i<0&&j<n)//判断行是否益处表格,如果益处了,就变成最下行坐标,
        {
            i=n-1;
        }
        else if(i<0&&j>=n)  /*判断行和列是否同时益处表格,如果益处了,行变为最下行坐标,
                            列变为最左边坐标*/
        {
            i=n-1;
            j=0;
        }
        else if(i>=0&&j>=n)//判断列是否单独益处表格,如果益处则变为最左边坐标
        {
            j=0;
        }
        if(nn[i][j]>0)//判断移动后的表格是否已经填入了数据,如果填入了,就不向右上移动,向下移动
        {
            i=iold+1;  //在记录上次的坐标向下移动一个表格
            j=jold;
       
        }

    }
    printf("______________________________\n 第1--4种\n\n");
    for(i=0;i<n;i++)//按照把得到的表格旋转和对撤后,所得到新的7种,
    {              //根据数组正序和倒序的排列输出可以实现

        for(j=0;j<n;j++)
        {
            printf(" %2d",nn[i][j]);
        }
        printf(" \t");
        for(j=n-1;j>=0;j--)
        {
            printf("%3d",nn[i][j]);
        }
        printf(" \t");
        for(j=0;j<n;j++)
        {
            printf("%3d",nn[j][i]);
        }
        printf(" \t");
        for(j=n-1;j>=0;j--)
        {
            printf("%3d",nn[j][i]);
        }
        printf("\n\n");

    }   
    printf("______________________________\n 第5--8种\n\n");
    for(i=n-1;i>=0;i--)
    {
       
        for(j=0;j<n;j++)
        {
            printf("%3d",nn[i][j]);
        }
        printf(" \t");
        for(j=n-1;j>=0;j--)
        {
            printf("%3d",nn[i][j]);
        }
        printf(" \t");
        for(j=0;j<n;j++)
        {
            printf("%3d",nn[j][i]);
        }
        printf(" \t");
        for(j=n-1;j>=0;j--)
        {
            printf("%3d",nn[j][i]);
        }
        printf("\n\n");

    }
    printf("______________________________\n");


}


[ 本帖最后由 啊C 于 2011-6-7 22:32 编辑 ]
搜索更多相关主题的帖子: 格子 编程 对角线 能力 
2011-06-06 19:20
voidx
Rank: 12Rank: 12Rank: 12
来 自:邯郸
等 级:火箭侠
帖 子:1250
专家分:3538
注 册:2011-4-7
收藏
得分:0 
这个我记得是往右上角移动还是怎么着
不小心在这里找到了:
http://zh.

[ 本帖最后由 voidx 于 2011-6-6 19:45 编辑 ]
2011-06-06 19:34
loveshuang
Rank: 9Rank: 9Rank: 9
来 自:湖北武汉
等 级:蜘蛛侠
帖 子:270
专家分:1198
注 册:2010-11-14
收藏
得分:1 
看这个行不行
程序代码:
#include <stdio.h>
//#include <stdlib.h>
#include <windows.h>
#define MAX 50

void main()
{
    system("title,魔方排数");
    printf("输入魔方的边,排出的方形数组中使每行、每列、对角线的元素之和都相等\n\n");
    int a[MAX][MAX]={0};
//    printf("%d",a[5][5]);
    int row;
    printf("输入魔方的边(要小于%d,且为奇数):",MAX);
    while(1)
    {
        scanf("%d",&row);
        if(row>MAX||row%2==0)
        {
            printf("输入值不正确,请重输:");
            continue;
        }
        else
            break;
    }
   
    int r=0;
    int c=row/2;
    a[r][c]=1;
    int i=0;
    int j=row/2;
    for(int num=2;num<=row*row;num++)
    {
        i=r-1;
        j=c-1;
        if(i<0)i=row-1;
        if(j<0)j=row-1;

        if(a[i][j]!=0)
        {
            i=(i+1)%row;
        }
        r=i;c=j;   
        a[i][j]=num;
       
    }

    printf("---------------------------------\n");
    for(i=0;i<row;i++)
    {
        for(j=0;j<row;j++)
            printf("%5d",a[i][j]);
        printf("\n");
           
    }
    printf("---------------------------------\n");


}

 
2011-06-06 20:20
topki
Rank: 1
等 级:新手上路
帖 子:12
专家分:4
注 册:2011-5-12
收藏
得分:0 
不会做啊。。留名等答案~~强烈要求加注释。

[ 本帖最后由 topki 于 2011-6-6 22:03 编辑 ]
2011-06-06 22:02
张义宇
Rank: 2
等 级:论坛游民
帖 子:40
专家分:37
注 册:2011-5-19
收藏
得分:0 
加油啦 慢慢来
2011-06-06 22:44
烟雾中的迷茫
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
帖 子:621
专家分:1069
注 册:2011-2-9
收藏
得分:0 
表示无奈 不怎么玩
2011-06-07 07:02
hjywyj
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:3
帖 子:1114
专家分:2611
注 册:2010-4-14
收藏
得分:0 
这不就是魔方阵吗?//又名纵横图。
2011-06-07 07:56
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:0 
程序代码:
#include <stdio.h>
#include <math.h>
#define N_MAX 51     // 最大为51阶幻方,如果支持C99,则可以省略这行,并去掉下面ms[N_MAX][N_MAX] = {0};最后在scanf("%d", &n);后添加
                     //   int ms[n][n];
                     //   for(i = 0; i < n; i++)
                     //       for(j = 0; j < n; j++)
                     //           ms[i][j] = 0; 

int main(void) {
    int n, x = 0, y, i, j, ms[N_MAX][N_MAX] = {0};
    char format[] = "%xd";
    printf("Enter n(1 to 51 and it's odd): ");    // 输出提示信息n为1 - 51并且n为奇数
    fflush(stdout);     // 保证输出上面的提示信息输出到stdout
    scanf("%d", &n);     // 输入n   
    if(n < 1 || !(n % 2)) {    // 不是奇数则输出提示信息,并退出
        printf("Unsupported operation!\n");
        return 1;
    } else {
        y = n / 2;    // 移到第一行中间
        for(i = ms[x][y] = 1; i < n * n; i++) {    // 从 1 to n * n - 1
            if((x - 1 == -1) && (y + 1 == n)) {     // 如果当前行、列在最右上角则下移一行
                x++;
            } else {
                x - 1 == -1 ? x = n - 1 : x--;     // x在0 to n - 1之间变化
                y + 1 == n ? y = 0 : y++;          // y在0 to n - 1之间变化
                ms[x][y] && (x += 2, y--);     // 如果当前行、列已被占则下移一行
            }
            ms[x][y] = i + 1;     // 把2 to n * n的值赋给当前行、列
        }
        format[1] = (int)(log10(n * n) + 2 + '0');    // 把'x'替换为每一个数所占的列数
        for(i = 0; i < n; i++) {    // 输出幻方
            for(j = 0; j < n; j++) {
                printf(format, ms[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}
图片附件: 游客没有浏览图片的权限,请 登录注册

图片附件: 游客没有浏览图片的权限,请 登录注册



[ 本帖最后由 lz1091914999 于 2011-6-7 17:10 编辑 ]

My life is brilliant
2011-06-07 09:34
草狼
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:2
帖 子:577
专家分:1040
注 册:2010-4-6
收藏
得分:0 
Algorithm Gossip: 奇数魔方阵
 
说明
 将1到n(为奇数)的数字排列在nxn的方阵上,且各行、各列与各对角线的和必须相同,如下所示:

 解法
 
填魔术方阵的方法以奇数最为简单,第一个数字放在第一行第一列的正中央,然后向右(左)上填,如果右(左)上已有数字,则向下填,如下图所示:

一般程式语言的阵列索引多由0开始,为了计算方便,我们利用索引1到n的部份,而在计算是向右(左)上或向下时,我们可以将索引值除以n值,如果得到余数为1就向下,否则就往右(左)上,原理很简单,看看是不是已经在同一列上绕一圈就对了。

#include <stdio.h>
#include <stdlib.h>

#define N 5

int main(void) {
    int i, j, key;
    int square[N+1][N+1] = {0};

    i = 0;
    j = (N+1) / 2;

    for(key = 1; key <= N*N; key++) {
        if((key % N) == 1)
            i++;
        else {
            i--;
            j++;
        }

        if(i == 0)
            i = N;
        if(j > N)
            j = 1;

        square[i][j] = key;
    }

    for(i = 1; i <= N; i++) {
        for(j = 1; j <= N; j++)
            printf("%2d ", square[i][j]);
    }

    return 0;
}




Algorithm Gossip: 4N 魔方阵
 
说明
 与 奇数魔术方阵 相同,在于求各行、各列与各对角线的和相等,而这次方阵的维度是4的倍数。
解法
 先来看看4X4方阵的解法:


简单的说,就是一个从左上由1依序开始填,但遇对角线不填,另一个由左上由16开始填,但只填在对角线,再将两个合起来就是解答了;如果N大于2,则以 4X4为单位画对角线:


至于对角线的位置该如何判断,有两个公式,有兴趣的可以画图印证看看,如下所示:
左上至右下:j % 4 == i % 4
右上至左下:(j % 4 + i % 4) == 1

#include <stdio.h>
#include <stdlib.h>

#define N 8

int main(void) {
    int i, j;
    int square[N+1][N+1] = {0};

    for(j = 1; j <= N; j++) {
        for(i = 1; i <= N; i++){
            if(j % 4 == i % 4 || (j % 4 + i % 4) == 1)
                square[i][j] = (N+1-i) * N -j + 1;
            else
                square[i][j] = (i - 1) * N + j;
        }
    }

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

    return 0;
}
2011-06-07 09:44
啊C
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:84
专家分:177
注 册:2010-6-24
收藏
得分:0 
今天晚上给代码,一共写出了8种,也就是说有8种算吧,我是使用的是排序不同而实现8种,
有兴趣的朋友可以试试用8种算法来实现!

亲爱的朋友们动起手来吧,让我们一起迈向C语言的世界!
2011-06-07 15:18
快速回复:每日一题!NO.3(适合新手做练习)-幻方问题(已经给出答案!)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.034465 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved