开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情
前言
本文是关于刷题——回型矩阵和蛇形矩阵的C语言实现。
新手一个,水平比较低,还请包涵。
回型矩阵
题目描述
给你一个整数n,按要求输出n∗n的回型矩阵
输入描述:
输入一行,包含一个整数n
1<=n<=19
输出描述:
输出n行,每行包含n个正整数.
示例:
输入:4
输出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
思路分析
口字形圈作为边界不断内缩。
代码
int main()
{
int n = 0;
scanf("%d", &n);
int matrix[25][25];
int i = 0;
int j = 0;
int top = 0;
int bottom = n - 1;
int left = 0;
int right = n - 1;
int num = 0;
while (num < n * n)
{
//上行
for (i = left; i < right; i++)
{
matrix[top][i] = ++num;
}
//右列
for (i = top; i < bottom; i++)
{
matrix[i][right] = ++num;
}
//下行
for (i = right; i > left; i--)
{
matrix[bottom][i] = ++num;
}
//左列
for (i = bottom; i > top; i--)
{
matrix[i][left] = ++num;
}
top++;
bottom--;
left++;
right--;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
蛇形矩阵
题目描述
给你一个整数n,输出n∗n的蛇形矩阵。
输入描述:
输入一行,包含一个整数n
输出描述:
输出n行,每行包含n个正整数,通过空格分隔。
1<=n<=1000
示例:
输入:4
输出:
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
思路分析
row表示行,col表示列,mtr[row][col]表示当前在哪个元素的位置上,用行下标和列下标控制“移动”。
设立一个方形边界,边长由变量limit控制,每次放入对角线上的元素,第一个和最后一个元素在这之前提前放好。
移动方向分为斜向上和斜向下,由变量dir控制,0为斜向下,1为斜向上,每轮过后!dir调转方向。
人为地把矩阵分为两部分:一个是上半包括对角线,另一个是下半不包括对角线。
方形边界先逐渐变大,存放上半部分数值,等到limit==n时说明上半部分和最大的对角线上的元素已经放入,这时再让方形边界逐渐变小,存放下半部分数值。
在不同部分时的移动方式有所差异
上面这张图的另一个边界应该改成limit,注意边界都不要取等号。
代码
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int mtr[1001][1001];//矩阵,不用变长数组省事一点(不用担心越界)
int limit = 2;//方形边界边长
int row = 0;//目前所在元素的行下标
int col = 0;//目前所在元素的列下标
int dir = 0;//0代表斜向下方向,1表示斜向上方向
int num = 2;//要放入的值,初始为2,因为第一个提前放入
int state = 0;//表示上半部分(0)还是下半部分(1)
mtr[0][0] = 1;//初始化第一个元素
mtr[n-1][n-1] = n*n;//初始化最后一个元素
int delta = 1;//limit增量,为正数时说明元素还在上半部分,为负数时说明元素在下半部分
int i = 0;//循环变量
int j = 0;//循环变量
while(num < n * n - 1)//记得-1,因为把最后一个元素提前放入了
{
if(!dir)//斜向下
{
if(!state)//元素在上半部分时
{
mtr[row][++col] = num++;//右移
while(col > 0 && row < limit)
{
//阶梯式斜向下移
mtr[++row][--col] = num++;
}
}
else//元素在下半部分时
{
mtr[++row][col] = num++;//下移
while(col > n - limit && row < n)
{
//阶梯式斜向下移
mtr[++row][--col] = num++;
}
}
}
else//斜向上
{
if(!state)//元素在上半部分时
{
mtr[++row][col] = num++;//下移
while(row > 0 && col < limit)
{
//阶梯式斜向上移
mtr[--row][++col] = num++;
}
}
else//元素在下半部分时
{
mtr[row][++col] = num++;//右移
while(row > n - limit && col < n)
{
//阶梯式斜向上移
mtr[--row][++col] = num++;
}
}
}
if(limit == n)//方形边界达到最大了,开始变小
{
delta = -delta;
state = 1;//开始下半部分了
}
limit += delta;//方形边界变化(变大或变小)
dir = !dir;//方向反转
}
for(i = 0; i < n; i++)//打印元素
{
for(j = 0; j < n; j++)
{
printf("%d ", mtr[i][j]);
}
printf("\n");
}
return 0;
}