矩阵的输入输出

  •  回形矩阵

输入一个数n,输出一个n*n阶回形矩阵。

例如输入:4

输出: 

1   2    3   4
12 13 14  5
11 16 15  6
10  9   8   7

想直接在屏幕上打印出这个图形是不现实的,应该按照其规律先储存进二维数组,再打印出来。 解题关键在于掌握其规律。

先从上边界往右开始依次加一,到达右边界时上边界向下移动一次,再沿最后一列往下依次加一,到达下边界时右边界向左移动一次,再沿最后一行往左依次加一,到达左边界时下边界向上移动一次,再沿第一列往上依次加一,到达上边界时左边界向右移动一次,至此最外圈输入完毕,同时各边界都向内移动多了一次,再重复上述操作......

知道了其变化规律,只需要定义一个x从1开始按照上边界、右边界、下边界、左边界的顺序依次自增对数组赋值即可,使用while语句和for语句进行嵌套限制,最后再按照打印二维数组的方法进行打印即可。

代码如下:

#include <stdio.h>
int main() 
{
    int arr[20][20], n;
    scanf("%d", &n);
    int up = 0, down = n - 1,left = 0, right = n - 1;//分别为上下左右边界
    int x = 1;//x为要存储的数且x依次增大
    while (x <= n * n)//全部输完后最后一个数字应为n*n
    {
        for (int i = left; i <= right; i++)//从左到右输入
        {
            arr[up][i] = x++;
        }
        up++;//上边界加1
        for (int i = up; i <= down; i++)//从上到下输入
        {
            arr[i][right] = x++;
        }
        right--;//右边界减1
        for (int i = right; i >= left; i--)//从右到左输入
        {
            arr[down][i] = x++;
        }
        down--;//下边界减1
        for (int i = down; i >= up; i--)//从下到上输入
        {
            arr[i][left] = x++;
        }
        left++;//左边界加1
    }
    for (int i = 0; i < n; i++)//依次输出
    {
        for (int j = 0; j < n; j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}
  •  蛇形矩阵

输入一个数n,输出一个n*n阶蛇形矩阵。

例如输入:4

输出: 

1    2   6    7
3    5   8   13
4    9  12  14
10 11 15  16

 这个矩阵与回形类似,但又有所不同。蛇形矩阵的赋值时,除了边界上的移动,还多了左上、右下的移动,并且在边界上每次只移动一,经过观察不难发现其规律。

沿右上移动至上边界时,在上边界向右移动一,并改变移动方向;沿左下移动至左边界时,在左边界向下移动一,并改变方向;沿右上到达右边界时,在右边界向下移动一,并改变方向;沿左下到达下边界时,在下边界向右移动一,并改变方向......

知道了其变化规律,具体实施时,可参照回形矩阵定义一个k,构建一个for语句和if else语句的嵌套,按顺序进行一一赋值即可。因为程序中都是++i、++j,所以第一个元素要自己直接赋值。

代码如下:

#include <stdio.h>
int main()
{
    int n = 0;
    int array[100][100] = { 0 };
    scanf("%d",&n);
    int i = 0, j = 0, k = 0,pos = 1; //pos代表方向移动,1代表右上,-1代表左下
    array[i][j] = 1;
    for (k = 2; k <= n*n; k++)
    {
        if (i == 0 && j <n-1 && pos ==1) //碰到上边界,列增加1,行不变;此后行增,列减
        {
            array[i][++j] = k;
            pos = -1;//调整方向
        }
        else if(j==0 && i<n-1 && pos == -1)//碰到左边界,行增加1,列不变;此后行减,列增
        {
            array[++i][j] = k;
            pos = 1;//调整方向                
        }
        else if (j == n-1 && pos==1) //碰到右边界,行增加1,列不变;此后行增,列减
        {
            array[++i][j] = k;
            pos = -1;//调整方向
        }
        else if (i == n-1 && pos ==-1) //碰到下边界,列增加1,行不变;此后行减,列增
        {
            array[i][++j] = k;
            pos = 1;
		}  
        else//中间移动过程
		{
			if (pos == 1)
			{
            	array[--i][++j] = k;
        	}
        	if( pos == -1)
        	{
            	array[++i][--j] = k;
        	}
		}  

        
    }
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
            printf("%d ",array[i][j]);
        printf("\n");
    }
    return 0;
}

蛇形矩阵除了上述方法,还可以只按右上、左下的顺序进行赋值,利用i,j的自增自减控制在边界上时开始赋值的位置即可。

代码如下:

#include<stdio.h>
int main()
{
	int k=0;//要打印的矩阵
	scanf("%d",&k);
	int tem = 1;//从1开始赋值
	int ret = 1;//记录移动方向,1表示往右上,-1表示往左下
	int i = 0, j = 0;
	int arr[100][100] = { 0 };
	while (tem <= k * k)
	{
		if (ret == 1)//往右上
		{
			for (;; i--, j++)
			{
				arr[i][j] = tem;
				tem++;
				if (i == 0 || j == k - 1)
				{//触碰到边界结束循环
					if (i == 0&&j!=k-1)
					{//落在上边界,且不是最右边的位置
						j++;
					}
					else 
					{//落在右边界
						i++;
					}
					ret = -1;
					break;
				}
			}
		}
		if (ret == -1)//左下
		{
			for (;; i++, j--)
			{
				arr[i][j] = tem;
				tem++;
				if (i == k - 1 || j == 0)
				{//触碰到边界结束循环
					if (i == k - 1)
					{//落在下边界
						j++;
					}
					else
					{//落在左边界
						i++;
					}
					ret = 1;
					break;
				}
			}
		}
	}
	for (i = 0; i < k; i++)
	{
		for (j = 0; j < k; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 

蛇形矩阵推广:

如下图所示,用从 1 开始的正整数“蛇形”填充无限大的矩阵。

1 2 6 7 15 ...
3 5 8 14 ...
4 9 13 ...
10 12 ...
11 ...
...

容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?

 因为是无限填充,则要保证所求数字在矩阵的上三角区域,才能避免错误输出,那么矩阵实际行列数至少是所求行列数的2倍

#include<stdio.h>
int main()
{
	int k=0;//要打印的矩阵
	scanf("%d",&k);
	int tem = 1;//从1开始赋值
	int ret = 1;//记录移动方向,1表示往右上,-1表示往左下
	int i = 0, j = 0;
	int arr[1000][1000] = { 0 };
	while (tem <= 4 * k * k)
	{
		if (ret == 1)//往右上
		{
			for (;; i--, j++)
			{
				arr[i][j] = tem;
				tem++;
				if (i == 0 || j == 2 * k - 1)
				{//触碰到边界结束循环
					if (i == 0&&j!=2 * k - 1)
					{//落在上边界,且不是最右边的位置
						j++;
					}
					else 
					{//落在右边界
						i++;
					}
					ret = -1;
					break;
				}
			}
		}
		if (ret == -1)//左下
		{
			for (;; i++, j--)
			{
				arr[i][j] = tem;
				tem++;
				if (i == 2 * k - 1 || j == 0)
				{//触碰到边界结束循环
					if (i == 2 * k - 1)
					{//落在下边界
						j++;
					}
					else
					{//落在左边界
						i++;
					}
					ret = 1;
					break;
				}
			}
		}
	}
    printf("%d\n",arr[k-1][k-1]);
    return 0;
}

 当然使用第一种方法也可实现,在这里就不再赘述,有兴趣的请自行尝试验证。

 对于上述无限填充的蛇形矩阵,除了利用程序暴力求解,也可以观察期规律快速求解。

 观察对角线上(行数、列数相等)的数字,可发现:

一行一列:1^2=1

二行二列:1^2+2^2=5

三行三列:2^2+3^2=13

四行四列:3^2+4^2=25

....... 

即n行n列的数为(n-1)^2+n^2

发现规律可快速求解。

今天的分享就到这里,如有不足之处欢迎大家指正!

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值