问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C语言求所有四阶幻方?

发布网友 发布时间:2022-04-27 00:32

我来回答

1个回答

热心网友 时间:2022-06-21 18:28

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

#define EVEN_DOUBLE_4 4//双偶的最基本类型,4阶双偶
#define SCREEN_SIZE 19//屏幕显示不变形的最大尺寸(主要是因为窗口大小*)
#define MIN_SIZE 3//最小阶数为3
#define MAX_SIZE 30
/*原则上是任意阶,算法是相同的,这里就以30为上限吧,
当然如果你愿意,可以修改的更大一些*/

#define PRINT printf("Esc退出,Enter继续"); //打印的宏
#define CLEAR row = 0; column = 0; //清零

int Magic[MAX_SIZE][MAX_SIZE]={0};//全局,幻方数组
int row = 0; column = 0;//全局,幻方的行列数

int main(void)
{
int read();//读取函数
void odd(int size, int ini_value );//奇数阶幻方生成
void mean_double_4(int size);//4阶双偶生成
void mean_double(int size);//双偶生成
void mean_single(int size);//单偶生成
void print_magic(int size);//打印幻方
void sum_print(int data[], int size);//行、列、对之和打印
void clear_sum(int data[]);
void check_magic(int data[], int size );//检查所得矩阵是否为幻方阵

int size;//幻方阶数
int sum[2*MAX_SIZE+2] = {0};//行、列、对之和

do{
CLEAR
clear_sum(sum);
size=read();
system("cls");

if(size%2 != 0 )odd(size, 0);
else if(size %4 == 0) mean_double(size);
else mean_single(size);

print_magic(size);
sum_print(sum, size);
check_magic(sum,size);
PRINT

}while (getch() != 27);

return 0;
}

/*读入数据*/
int read()
{
int min_size = MIN_SIZE;
int max_size = MAX_SIZE;
int size;

do{
printf("请输入幻方阶数n,n∈[%d,%d]\n", min_size, max_size);
scanf("%d", &size);
getchar();
if(size<3 || size > MAX_SIZE) printf("非法输入,请重新输入[%d,%d]的正整数\n", min_size, max_size);
else if(size > SCREEN_SIZE){
printf("大于屏显最大阶数,输出将变形\n");
Sleep(2000);
}
}while(size < MIN_SIZE || size > MAX_SIZE);

return size;
}

/*奇数阶幻方,采用house法*/
void odd(int size, int ini_value)
{
int num; //填充数字
int min_num = 1+ini_value;
int max_num = 1+size*size+ini_value;//填充范围
int x = size/2;
int y = 0;//初始填充坐标

for(num = min_num; num < max_num; num++){
Magic[y+row][x+column] = num;
if(num % size == 0) y++; //跳步
else x++, y += 2;//马步,其实Horse法和Siamese是完全类似的
x = x % size ;
y = y % size ;
/*越界反弹,即触碰到边界,从另一边返回*/
}
}

/*双偶数阶幻方,采用对调法*/

/*对调法的基础,4阶双偶。注意要求是将非主副对角线上的元素对调,
其实换个角度,你也可以说就是把祝福对角线中心对调。只不过两种思路得到的矩阵
正好是反着来的*/
/*本函数实现主副对角线互调*/
void mean_double_4(int size)
{

int i;
int total = size * size +1 ;
for(i = 0; i < EVEN_DOUBLE_4; i++){
Magic[row+i][column+i]= total - Magic[row+i][column+i];
Magic[row+i][ EVEN_DOUBLE_4+column-i-1] =
total - Magic[row+i][ EVEN_DOUBLE_4+column-i-1];
}

}

/*任意阶双偶*/
void mean_double(int size)
{
int num; //填充数字
int min_num = 1;
int max_num = 1+size*size;//填充范围
int i = 0;//循环变量
int temp;

/*双偶,初始化*/
for(num = min_num; num < max_num; num++){
Magic[row][column] = num;
if((num ) % (size ) == 0){
column = 0, row++;
}
else column++;
}

/*分割为4×4的小矩阵*/
row = 0; column = 0;
temp = size / EVEN_DOUBLE_4;

for(i = 1; i <=temp *temp; i++){
mean_double_4(size);
if(i % temp == 0) column = 0, row += 4 ;
else column = (i % temp) * EVEN_DOUBLE_4;
}
}

/*单偶,用楼梯法*/
void mean_single(int size)
{
int i,j,k,m;
int temp;

/*分象限处理,
14
32
与普通直角坐标系象限区别,说白了,就是个分块的概念
*/
row = 0, column = 0;//第一象限
odd(size/2, 0);

row = size/2, column = size/2;//第二象限
odd(size/2, (size*size)/4*1);

row = 0, column = size/2;//第三象限
odd(size/2, (size*size)/4*2);

row = size/2, column = 0;//第四象限
odd(size/2, (size*size)/4*3);

m = size / 4;

/*对换*/
for(i = 0; i< size/2; i++){
/*1、3象限对换*/
for(j = 0; j<m; j++ ){
if(i == m) k = j + m;
else k = j;
temp = Magic[i][k];
Magic[i][k] = Magic[i + 2*size/4 ][k];
Magic[i + 2*size/4 ][k] = temp;
}
/*2,4对换*/
for(j = 0; j<m-1; j++ ){
k = 3*size/4 +j;
temp = Magic[i][k];
Magic[i][k] = Magic[i + 2*size/4][k];
Magic[i + 2*size/4][k] = temp;
}
}
}

/*打印幻方*/
void print_magic(int size)
{
int i,j;
for(i = 0; i < size; i++)
for(j = 0; j < size; j++){
printf("%4d", Magic[i][j]);
if(j == size -1) putchar('\n');
}
putchar('\n');
}

/*打印各行、各列、各对角线数据之和*/
void sum_print(int data[], int size)
{
int i,j;

/*打印每行数据之和*/
printf("行之和:");
for(i = 0; i < size; i++)
for(j = 0; j < size; j++){
data[i] += Magic[i][j];//行之和
if (j == size -1) printf("%6d", data[i]);
}
putchar('\n');

/*打印每列数据之和*/
printf("列之和:");
for(i = 0; i < size; i++)
for(j = 0; j < size; j++){
data[size+i] += Magic[j][i];//列之和
if (j == size -1) printf("%6d", data[size+i]);
}
putchar('\n');

/*打印主对角线之和*/
for(i=0; i<size; i++)
data[2*size] += Magic[i][i];
printf("主对角线之和:%6d", data[2*size]);
putchar('\n');

/*打印副对角线之和*/
for(i=0; i<size; i++)
data[2*size+1] += Magic[i][size-i-1];
printf("主对角线之和:%6d", data[2*size]);
putchar('\n');

}

/*行列对和数组清零*/
void clear_sum(int data[])
{
int i;
for(i = 0; i < 2 * MAX_SIZE; i++)
data[i] = 0;
}

/*检查程序是否运转正常,所得结果是否是幻方*/
void check_magic(int data[], int size )
{
int i;
int flag = 0;
for(i=1; i<size+2;i++)
if(data[0]-data[i]) flag = 1;
if(flag) printf("程序出错,Esc退出,Enter继续\n");
else printf("\n恭喜你,获得了一个新的%d阶幻方!\n", size);
putchar('\n');

}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
华硕X205TABIOS里launchcsm这个选项怎么找 朋友在一起,本来想着相互花钱不要计较那么多的,结果对方却老是想着比... 别人叫你请他吃东西,那他是不是不讨厌你。算是给你机会吗?? 哪种乌冬面比较好吃 ...膳,你小时候最爱吃那儿的豌豆黄儿。还记得那回我带你去北海吗... 苍梧鸟是什么意思? 右手五指受伤其中小指无名指各截掉一节可评几级伤残 ...桡骨骨折伤残鉴定怎么算呢,是左手的算左手的右手算右手,还是一起算... 工伤伤残鉴定中,对右手左手有区别吗? 车子出了事故,4s店在维修合同上写的交车日期,如果4s店超出预订时间交车... 跪求c语言编程问题,把算法写出来 哈夫曼树译码的算法思路,语言描述即可 谁帮忙解释一下该C语言的算法思想 用C语言编写可以进行加减乘除整数运算混合运算的计算器,要求写思路,越详细越好,初学者,不要很复杂的。 求两个集合交集的算法 迭代法是什么? 排序算法性能比较(数据结构)C语言程序 数据结构:用什么算法可以走出迷宫? 多项式 求根的算法和程序 【急!在线等】求指点如何计算股权融资成本,用CLS模型 想了解股票正,负成交量指标的计算法,可是公式中的CLS不知代表什么,请教各位大侠 希尔排序算法 苹果手机屏幕左上角黑了一块,怎么回事 清明节为什么要挂柳树枝 柳枝有什么药效? 借问柳枝有寄否,古今共有几多愁 柳树有哪些特点 柳树枝怎么种 柳树枝的汁液养花有哪些好处? 柳树有哪些特点? 大神们 苹果用什么助手可以免费下载 狂野飙车7?在线等 椭圆成生算法 爱思助手怎么搜索不到狂野飙车7? ID3算法的介绍 狂野飙车7iPhone怎么下载 iphone狂野飙车7 ipad平板电脑如何安装狂野飙车7 ipod touch5需要越狱吗?如果不越狱,怎么下载大型游戏(如狂野飙车7,圣徒之城里约热内卢等)去哪可以下 今天在快用苹果助手下载了一个狂野飙车7,进入游戏时需要输入ID,可是我输入好ID后还是进不去游戏, 为什么我的Iphone4运行不了狂野飙车7??? 想更新Iphone4的狂野飙车7、怎么显示内存不足呢?我还有3G多的内存啊?怎么回事啊? iPhone4s无法下载安装狂野飙车7:极速热力 iPhone4s狂野飙车7不能安装 狂野飙车7IPHONE版昨天开始限免为什么下载不了 我的电话是4S 版本6.0.1 苹果狂野飙车7提示无法连接itunes store 我是用苹果助手下的 描写夏天的一段话(150字左右) 建筑给水系统的给水方式有哪几种 建筑给水系统的给水方式有哪几种,分别说明它们的适用条件 说出四种给水方式的基本形式及他们的优缺点是什么? 给水系统中不同给水方式的特点?