打印数字三角及蛇形矩阵(C语言)

题目描述:
从键盘输入N,输出如下图所示的N行的数字三角.
例如: N = 5,那么输出如下:
在这里插入图片描述
输入格式:
输入一个整数N,1<= N <= 45
输出格式:
输出如题所示的数字三角形,为了输出美观,每个数字栈5个字符位,右对齐(即%5d)

解题的思路:
1、定义一个45行45列的二维数组arr[N][N],用于存放对应的值
2、定义两个数组,表示它在x方向、y方向上的移动方向,并分别对这两个数组进行初始化。move_x[3] = {1,0,-1},move_y[3] = {0,1,-1},之所以这样初始化,是因为由上面图示可以直到,移动只有3个方向,向下,向右,斜上,所以如果move_x的值为0,表示向右移动,为1表示向下移动,-1表示斜上;move_y的值为0表示向下,值为1表示向右,-1表示斜上
3、定义x,y表示当前的位置,a、b表示当前位置的下一格,用于判断是否需要改变方向,d表示当前方向的下标,如果d = 0,那么move_x[0] = 1,move_y[0] = 0,说明是向下移动的,其他的同理。
改变方向的条件:如果arr[a]\[b]的值不为0,表示这一步已经走过了,那么就改变方向,如果a、b的值导致数组发生了越界,那么同样需要改变方向。这时候只要修正d的值,然后将a = x + move_x[d],b = y + move_y[d]操作即可实现方向改变

代码实现:

#include<stdio.h>
#define N 45
int main(){
  int i,j,n;//n表示数组是多少行
  int arr[N][N]={0};//将数组初始化为0,表示没有走过
  int move_x[3] = {1,0,-1},move_y[3] = {0,1,-1};//定义两个数组,表示移动的方向
  int x = 0,y = 0,a = 0,b = 0,d = 0,count = 1;//count统计各个下标下的值,定义x,y有必要的
  scanf("%d",&n);
  for(i = 0; i < n; i++){
    for(j = 0; j <= i; j++){
        //printf("d = %d, a = %d ,b = %d,x = %d ,y = %d ,count = %d\n",d,a,b,x,y,count);--可以检验移动的值是否正确
        /*
        有同学问这样是否可以呢?答案是否定的,为什么?
        这时候我们举一个例子就知道了,如果我们输入的n为5,那么这时候如果
        当前已经走到了arr[4][0]这个位置,执行arr[4][0] = 5之后,这时候
        及进行a = a + move_x[d] = 5,b = b + move_y[d] = 0,明显的是
        a >= n了,此时就进入到了if语句进行修改移动的方向,这时候d = 1,
        重点就是这里,这时候a = a + move_x[d] = 5 + 0 = 5,b = b +      
        move_y[d] = 0 + 1 = 1,发现同样是发生了越界,所以这样是不正确的。
        arr[a][b] = count;
        a = a + move_x[d];
        b = b + move_y[d];
        if(a < 0 || a >=n || b < 0 || b >=n || arr[a][b]){
            //如果发生了越界,或者这一部已经走过了,那么就更换方向
            d = (d + 1) % 3;
            a = a + move_x[d];
            b = b + move_y[d];
        }
        */
        arr[x][y] = count;//当前的位置
        a = x + move_x[d];//获取当前位置移动的下一格,然后判断是否会发生越界或者是否已经走过了,如果是,那么就修改移动方向
        b = y + move_y[d];
        if(a < 0 || a >=n || b < 0 || b >=n || arr[a][b]){
            //如果发生了越界,或者这一部已经走过了,那么就更换方向
            d = (d + 1) % 3;
            a = x + move_x[d];
            b = y + move_y[d];
        }
        x = a;
        y = b;
        count++;
    }
  }

  for(i = 0; i < n; i++){
    for(j = 0; j <= i; j++){
        printf("%5d",arr[i][j]);//将数字输出,并且按照右对齐的方式输出
    }
    printf("\n");
  }
  return 0;
}

运行结果:
在这里插入图片描述

如果不是三角形,是一个方形怎么办呢?其实理解了上面之后,解题就很简单了,只要将移动方向的数组变成4格方向即可,分别初始它的值为: move_x[4] = {1,0,-1,0},其中move_x[0]表示向下移动,move_x[1]表示向右移动,move_x[2]表示向上运动,move_x[3]表示向左移动.move_y[4] = {0,1,0,-1},其中move_y[0]表示向下运动,move_y[1]表示向右移动,move_y[2]表示向上移动,move_y[3]表示向左移动值得一提的是,如果对应的移动方向要求不是这样的话,那么就需要重新进行修改move_x,move_y数组的值.
这时候,如果输入的是5,那么最后输出的是如下图:
在这里插入图片描述
对应的代码:

#include<stdio.h>
#define N 45
int main(){
  int i,j,n;
  int arr[N][N]={0};
  int move_x[4] = {1,0,-1,0},move_y[4] = {0,1,0,-1};//定义两个数组,表示移动的方向
  int x = 0,y = 0,a = 0,b = 0,d = 0,count = 1;//count统计各个下标下的值
  scanf("%d",&n);
  for(i = 0; i < n; i++){
    for(j = 0; j < n; j++){
        //printf("d = %d, a = %d ,b = %d,x = %d ,y = %d ,count = %d\n",d,a,b,x,y,count);
        arr[x][y] = count;
        a = x + move_x[d];
        b = y + move_y[d];
        if(a < 0 || a >=n || b < 0 || b >=n || arr[a][b]){
            //如果发生了越界,或者这一部已经走过了,那么就更换方向
            d = (d + 1) % 4;//由于有4个方向,那么就要%4
            a = x + move_x[d];
            b = y + move_y[d];
        }
        x = a;
        y = b;
        count++;
    }
  }
  printf("\n");
  for(i = 0; i < n; i++){
    for(j = 0; j < n; j++){
        printf("%5d",arr[i][j]);
    }
    printf("\n");
  }
  return 0;
}

运行结果:
在这里插入图片描述
蛇形矩阵:
输入样例:5
输出:
在这里插入图片描述
通过图片分析,我们可以知道,每一行都是向着斜向上的方向移动,所以这时候我们可以通过循环即可实现向斜向上的方向移动,只需要改变对应的下标即可
对应的代码:

#include<stdio.h>
#define N 45
int main(){
  int arr[N][N] = {0};
  int n;
  int a = 0,b = 0,count = 1,i,j;//x、y表示当前的位置
  printf("请输入N:");
  scanf("%d",&n);
  for(i = 0; i < n; i++){
    a = i;
    b = 0;//重置a、b,使得a一开始等于i,b等于0
    for(j = 0; j <= i; j++){
        arr[a--][b++] = count++;//改变对应的下标即可实现向着斜向上的方向移动
    }
  }
  //输出的时候需要注意,他并不是第i行就有i个数,相反,第i行他就有n - i个数
  for(i = 0; i < n; i++){
    for(j = 0; j < n - i; j++){
        printf("%5d",arr[i][j]);
    }
    printf("\n");
  }
  return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值