代码:
杨辉三角题目较为简单,魔方阵题目实现了输出任意整数即可输出对应的魔方阵
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
//输出杨辉三角
void q5_6() {
int arr[10][10]; //要求输出10行
int i, j;
//杨辉三角每一行最左最右都为1
for (i = 0; i < 10; i++) {
arr[i][0] = 1;
arr[i][i] = 1;
}
//其他数为上一行该位置对应的数与其左边数之和
for (i = 2; i < 10; i++) {
for (j = 1; j < i; j++) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
}
//输出
for (i = 0; i < 10; i++) {
for (j = 0; j <= i; j++) {
printf("%d", arr[i][j]);
//为了对齐,不同位数加上不同的空格
if (arr[i][j] / 1000 != 0)
printf(" ");
else if (arr[i][j] / 100 != 0)
printf(" ");
else if (arr[i][j] / 10 != 0)
printf(" ");
else
printf(" ");
}
printf("\n");
}
}
/*输出魔方阵
奇
1.第一个元素放在第一行中间一列
2.下一个元素存放在当前元素右上方也就是上一行、下一列。
3.如果上一行、下一列已经有内容,则下一个元素的存放位置为当前列的下一行。
在寻找的过程中,如果行数,列数<0或>n-1,即超出了矩阵范围,将其视为回环的,0变为n-1,n-1变为0
偶,4的倍数
按数字从小到大,即1,2,3……n2顺序对魔方阵从左到右,从上到下进行填充;
将魔方阵分成若干个4×4子方阵,将子方阵对角线上的元素取出;
将取出的元素按从大到小的顺序依次填充到n×n方阵的空缺处。
偶,4的倍数-2
将魔方分成A、B、C、D四个k阶方阵,这四个方阵都为奇方阵,利用上面讲到的方法依次将A、D、B、C填充为奇魔方。
交换A、C魔方元素,对魔方的中间行,交换从中间列向右的m列各对应元素;对其他行,交换从左向右m列各对应元素。
交换B、D魔方元素,交换从中间列向左m – 1列各对应元素。
*/
void q5_7_ji(int n) {
int i, j;
int row, col;
int lrow, lcol; //保存上一步数据,用于还原
//动态二维数组
int **a = (int **)malloc(n * sizeof(int*));
for (int i = 0; i < n; i++)
{
a[i] = (int *)malloc(n * sizeof(int));
}
for (i = 0; i < n; i++)//初始化赋值为0
{
for (j = 0; j < n; j++)
a[i][j] = 0;
}
row = 0;
col = (n - 1) / 2;
a[row][col] = 1;
for (i = 2; i <= n * n; i++)
{
row--;
col++;
if (row < 0)
row = n - 1;
if (col >= n)
col = 0;
if (a[row][col]) //若是上一行下一列处有数据了,我们就要将下标还原,行数加一
{
row = lrow + 1;
col = lcol;
if (row >= n)
row = 0;
}
lcol = col;
lrow = row;
a[row][col] = i;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%5d", a[i][j]);
printf("\n");
}
}
void q5_7_ou_2(int n) {
//输出魔方阵
int i, j, k, temp;
int row, col;
int lrow, lcol;
int **a = (int **)malloc(n * sizeof(int*));
for (int i = 0; i < n; i++)
{
a[i] = (int *)malloc(n * sizeof(int));
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
a[i][j] = 0;
}
while (1)
{
if (n % 4 == 2)
break;
}
//步骤一:构建四个子方阵ADBC
//先构建A,然后对A进行每个元素加即可得到所有的子方阵
k = n / 2;
row = 0;
col = (k - 1) / 2;
a[row][col] = 1;
for (i = 2; i <= k * k; i++)
{
row--;
col++;
if (row < 0)
row = k - 1;
if (col >= k)
col = 0;
if (a[row][col])
{
row = lrow + 1;
col = lcol;
if (row >= k)
row = 0;
}
lcol = col;
lrow = row;
a[row][col] = i;
}
//按照顺序构建DBC方阵
for (row = 0; row < k; row++)
{
for (col = 0; col < k; col++)
{
a[row + k][col + k] = a[row][col] + k * k; //D子方阵
a[row][col + k] = a[row][col] + 2 * k*k; //B子方阵
a[row + k][col] = a[row][col] + 3 * k*k; //C子方阵
}
}
//步骤二:交换AC子方阵的数据
//1.先交换中间行的右半部分的m列,N=2*(2*m+1),k=2*m+1,m=(k-1)/2,所以这里的m是不包含最后一列的,包含中间列
//2.对于其他行,将会每行的前半部分
for (row = 0; row < k; row++)
{
if (row == k / 2) //中间行
{
for (col = k / 2; col < k - 1; col++)
{
temp = a[row][col];
a[row][col] = a[row + k][col];
a[row + k][col] = temp;
}
}
else //其他行,交换前m列,不包含中间列
{
for (col = 0; col < k / 2; col++)
{
temp = a[row][col];
a[row][col] = a[row + k][col];
a[row + k][col] = temp;
}
}
}
//步骤三:交换BD子方阵,交换中间列向左m-1列
for (row = 0; row < k; row++)
{
for (i = 0; i < (k - 1) / 2 - 1; i++)
{
temp = a[row][k + k / 2 - i];
a[row][k + k / 2 - i] = a[row + k][k + k / 2 - i];
a[row + k][k + k / 2 - i] = temp;
}
}
//步骤四:输出魔方阵
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%5d", a[i][j]);
printf("\n");
}
}
void q5_7_ou(int n) {
//如果是4的倍数-2阶使用另外的函数
if (n % 4 == 2) {
q5_7_ou_2(n);
return;
}
//如果是4的倍数阶
int i, j;
int row, col;
//动态二维数组
int **a = (int **)malloc(n * sizeof(int*));
for (int i = 0; i < n; i++)
{
a[i] = (int *)malloc(n * sizeof(int));
}
//用于存放各个子方阵的主对角线
int *tempArray = (int *)malloc(n*n/2 * sizeof(int*));
for (int i = 0; i < n*n/2; i++)
{
tempArray[i] = 0;
}
//将数据按顺序填充
i = 1;
for (row = 0; row < n; row++)
for (col = 0; col < n; col++)
a[row][col] = i++;
//将数据全部分为4X4子方阵,取出其中的主对角线,按照大小排序
i = 0;
for (row = 0; row < n; row++)
{
for (col = 0; col < n; col++)
{
if ((col % 4 == row % 4) || ((col % 4 + row % 4) == 3))
{
tempArray[i] = a[row][col];
i++;
}
}
}
//步骤三:将数据从大到小放入之前的子方阵对角线上
i--;
for (row = 0; row < n; row++)
{
for (col = 0; col < n; col++)
{
if ((col % 4 == row % 4) || ((col % 4 + row % 4) == 3))
{
a[row][col] = tempArray[i];
i--;
}
}
}
//步骤四:输出魔方阵
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%5d", a[i][j]);
printf("\n");
}
}
int main() {
//q5_6();
int n;
while(1){
printf("请输入阶数:");
scanf_s("%d", &n);
if (n % 2 == 0) {
q5_7_ou(n);//偶数
}
else {
q5_7_ji(n);//奇数
}
}
system("pause");
return 0;
}
运行截图:
杨辉三角:
魔方阵:
参考: