首页 > 试题广场 >

蛇形矩阵

[编程题]蛇形矩阵
  • 热度指数:180688 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}你需要输出一个 nn 列的上三角形蛇形矩阵。
\hspace{15pt}具体的构造方法为,从 1 开始填充自然数,记第 i 行第 1 列的元素为 a_{i,1}=k ,将其右上角的元素 a_{i-1,2},a_{i-2,3},\cdots,a_{1,i} 依次赋值为 k+1, k+2, \cdots, k+i-1 ,随后,将 a_{i,2} 赋值为 k+i ,并重复上述过程,直到填满上三角范围 \frac{n(n+1)}{2} 个格子。

输入描述:
\hspace{15pt}在一行上输入一个整数 n \left(1 \leqq n \leqq 100\right) 代表矩阵的大小。


输出描述:
\hspace{15pt}输出一个 nn 列的上三角蛇形矩阵。
示例1

输入

4

输出

1 3 6 10
2 5 9
4 8
7

说明

\hspace{15pt}第一步,k=1 ,将 a_{1,1}=1
\hspace{15pt}第二步,k=2 ,将 a_{2,1}=2a_{1,2}=3
\hspace{15pt}第三步,k=4 ,将 a_{3,1}=4a_{2,2}=5a_{1,3}=6
\hspace{15pt}第四步,k=7 ,将 a_{4,1}=7a_{3,2}=8a_{2,3}=9a_{1,4}=10
\begin{bmatrix}<br /> \color{orange}{1} &  &  &  \\<br />  &  &  &  \\<br />  &  &  &  \\<br />  &  &  &  <br />\end{bmatrix}<br />\to<br />\begin{bmatrix}<br /> 1 & \color{orange}{3}  &  &  \\<br /> \color{orange}{2} &  &  &  \\<br />  &  &  &  \\<br />  &  &  &  <br />\end{bmatrix}<br />\to<br />\begin{bmatrix}<br /> 1 & 3 & \color{orange}{6} &  \\<br /> 2 & \color{orange}{5} &  &  \\<br /> \color{orange}{4} &  &  &  \\<br />  &  &  &  <br />\end{bmatrix}<br />\to<br />\begin{bmatrix}<br /> 1 & 3 & 6 & \color{orange}{10} \\<br /> 2 & 5 & \color{orange}{9} &  \\<br /> 4 & \color{orange}{8} &  &  \\<br /> \color{orange}{7} &  &  &  <br />\end{bmatrix}
发表于 2025-02-09 14:50:39 回复(0)
# 动态数组避免直接定义100x100数组。
#include <stdio.h>
#include <stdlib.h>

int main() {
    int num, i, j, count = 1; //num表示几行几列的上三角
    scanf("%d", &num);
    if (num < 0 || num > 100) {
        return -1;
    }

    int** arr = (int**)malloc(num * sizeof(int*));  //申请空间
    for (i = 0; i < num; i++) {
        arr[i] = (int*)malloc(num * sizeof(int));  //申请空间
    }

    //赋值二维数组
    for (i = 1; i <= num; i++) {
        for (int j = 0; j < i; j++) {
            /* 从0行开始,但是i初始化为1,所以减去一,
             * 再减去此刻j的值,光标跳入斜对角线下一个位置准备赋值
             */
            arr[i - 1 - j][j] = count;
            count++;
        }
    }

    //打印二维数组
    //因为元素不会是0,故可以直接整个打印,由判断决定是否打印输出
    for (i = 0; i < num; i++) {
        for (j = 0; j < num; j++) {
            if (arr[i][j] > 0) {
                printf("%d ", arr[i][j]);
            }
        }
        printf("\n");
    }

    //释放空间
    for (i = 0; i < num; i++) {
        free(arr[i]);
    }
    free(arr);
    return 0;
}


发表于 2024-11-05 16:03:04 回复(0)
//老实人做法,蛇形赋值最后输出,通俗易懂
#include<stdio.h>

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        int arr[100][100], num = 1;
        int i = 0, j = 0;
        arr[0][0] = num++;
        while (j != n - 1) {
            if (i == 0) {
                i = j + 1;
                j = 0;
                arr[i][j] = num++;
            }
            arr[--i][++j] = num++;
        }
        for (i = 0; i < n; i++) {
            for (j = 0; j + i < n; j++) {
                printf("%d ", arr[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

发表于 2024-09-12 19:13:19 回复(0)
#include<stdlib.h>
#include<stdio.h>
int main()
{
    /*确定行数*/
    int n;
    scanf("%d", &n);
    /*按公式输出,第[i][j]位置的数为(i + j)*(i + j + 1) / 2 + j + 1*/
    for (int i = 0; i <= n-1; i++)
    {
        for (int j = 0; j <= n-i-1; j++)
        {
            printf("%d ", (i + j)*(i + j + 1) / 2 + j + 1);
        }
        printf("\n");
    }
    system("pause");
    return 0;
}
发表于 2024-09-05 09:59:38 回复(0)
卡了好久啊
#include <stdio.h>
int main() {
    int n=0;
    scanf("%d", &n);
    int i=0,j=0;
    int num=1;
    for(i=0;i<n;i++){
        num = num+i;
        int temp = num;
        for(j=0;j<n-i;j++){
            printf("%d ", temp);
            temp=temp+j+2+i;
        }
        printf("\n");
    }
    return 0;
}

发表于 2024-08-06 11:45:55 回复(0)
#include <stdio.h>

int main() {
    int a, b=1;
    scanf("%d",&a);
    for(int i=0;i<a;i++)//横行的等差数列比纵行的等差数列大1
    {
        b+=i;
        int num=b;
        for(int j=i;j<a;j++)
        {
            if(j>i)
                num+=j+1;
            printf("%d ",num);
            if(j==a-1)
                printf("\n");
        }
    }
    return 0;
}

发表于 2024-04-27 11:47:33 回复(0)
#include <stdio.h>

int main() {
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n-i+1;j++)
            printf("%d ",1+i*(i-1)/2+(j-1)*((i+1)+(i+j-1))/2);/*除以2要写在最后,写在前面可能会出现小数,小数点后的数会被舍弃而造成误差*/
        printf("\n");
    }
    return 0;
}
编辑于 2024-03-12 22:51:48 回复(0)
#include <stdio.h>
int main(int argc, char const *argv[])
{
    int a,i,j,k;
    k=0;
    scanf("%d",&a);
    int str[a];
    for (size_t i = 0; i < a; i++)
    {
        k+=i+1;
        str[i]=k;
        printf("%d ",k);
    }
    for (size_t j = 1; j < a; j++)
    {
        printf("\n");
        for (size_t i = j; i < a; i++)
        {
            k=str[i]-j;
            printf("%d ",k);
        }
    }
    return 0;
}

编辑于 2024-02-18 16:44:42 回复(0)
思路:
任意元素行列为dim2_arr[i][j];
斜行总数为N;
第一个斜行只有一个元素1,行列相加i+j = 0,0<1 = N;
第二个斜行有两个元素2 3,改行任意元素的行列相加均为i+j = 1,1<2 = N
第三个斜行有三个元素4 5 6,改行任意元素的行列相加均为i+j = 2,2<3 = N
...
根据所在的斜行,对斜行行数进行循环赋值即可
#include <stdio.h>
#include <stdlib.h>

int main() {
    int N = 0;
    int Slanted_rows = 1,element = 1;   //以斜行的视角观察,初始只有1行斜行
    scanf("%d\n",&N);
    int dim2_arr[100][100] = {0};
    for(;Slanted_rows <= N;Slanted_rows++){         //斜行数小于等于总斜行数
        for(int i = 0; i < Slanted_rows ; i++){     //观察到行列相加为总行数N - 1
            dim2_arr[Slanted_rows - i - 1][i] = element;
            element++;
        }
    }
    for(int i = 0 ; i < N ; i++){
        for(int j = 0; j + i < N; j++){
            printf("%d ",dim2_arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}


发表于 2023-12-23 00:37:11 回复(0)
惭愧,找规律找半天,实现又搞半天
思路:
(1)使用n*n的二维数组存数据,找到数字之间的规律,由a[0][0]来1生万物。
    我这找到的规律是:行内,a[i][j] = a[i][j-1] + i +j +1;同一列a[i][j] = a[i-1][j] + i+ j。
(2)从1开始每行的列挨个计算完,再计算下一行。
    比较容易出错,比如列循环的时候j得从1开始。计算下一行的第一个又得放在列循环之后。行循环的i++又得放在计算下一行得第一个之前。
(3)输出得时候,也需要每次输出得列数少1个。
总结起来:比较笨。
#include <stdio.h>
#include <stdlib.h>
int main() {
    int i = 0, j = 0, xstep = 0, ystep = 0;
    int row, col;

    scanf("%u", &row);
    col = row;
    unsigned int a[row][col];
    memset(a, 0, sizeof(a));

    a[0][0] = 1;
    for (i = 0; i < row;) {
        for (j = 1; j < col; j++) {
            a[i][j] = a[i][j - 1] + i + j + 1;
        }

        i++;
        j = 0;
        a[i][j] = a[i - 1][j] + i + j;
    }

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


发表于 2023-11-26 10:17:02 回复(0)
#include <stdio.h>

int main() {
    int N = 0;
    while (scanf("%d", &N) != EOF) {
        int num = (N + 1) * N / 2;
        int ret = 1;
        for (int i = 0; i < N; i++)
        {
            //第一列应该是1+0/+1/+2/+...N-1,所以应该是ret +=i;i:0~N-1
            ret += i;
            printf("%d ", ret);
            //每一行的后面元素都是从第一个元素往后加,所以是ret1 += tmp;第一行是加2~N;第二行是加3~N;依次类推到N;所以第一个加数是tmp=2+i;且tmp<=N;tmp++;
            int tmp = 2+i;
            int ret1 = ret;
            for (int j = 0; j < N - 1 && tmp <= N; j++)
            {
                ret1 += tmp;
                printf("%d ", ret1);
                tmp++;
            }
            printf("\n");
        }
    }
    return 0;
}
发表于 2023-10-10 20:06:27 回复(0)
#include <stdio.h>

int main() {
    int N;
    scanf("%d",&N);
    int a=1;
    for(int i=1;i<=N;i++)//行数逐行加1
    {
        int fir=a,t=fir;
        printf("%d ",fir);//每行第一个数
        for(int j=2;j<=N-i+1;j++)//单行逐个加1
        {
            t+=j+i-1;
            printf("%d ",t);
        }
        a+=i;
        printf("\n");
    }
    return 0;
}
发表于 2023-09-03 21:40:58 回复(0)
#include <stdio.h>

void prt(int head, int line, int n) {          //单行打印函数
    int i;
    for (i = 1 ; i <= n + 1 - line; i++) {     //第 line 行打印 n-line+1 个数
        printf("%d ", head);
        head += (line + i);                    //每行第 i 个元素相比前一个,大 line+1
    }
    printf("\n");
}

int main() {
    int n, i, head = 1;
    scanf("%d", &n);

    for (i = 1 ; i <= n ; i++) {               //循环所有行   1~n行
        head += (i - 1);
        prt(head, i, n);                 //每行调用单行打印函数
    }


    return 0;
}

发表于 2023-04-03 20:50:53 回复(0)
#include <stdio.h>
#include <stdlib.h>

int main() {
    int n;
    int matrix[100][100] = {0};
    int preFirstColi = 0;   //存储第一列的上一次更新的的i,作为起始位置
    scanf("%d", &n);
    for(int j=0, i=0, cur=1; ; cur++){//ij为矩阵的索引, cur为递增的自然数
        
        matrix[i][j] = cur;     //将cur放入矩阵,
        if(i==0){               //当递增到第一行
            if(j == n-1)            //判断是否已经到目标的n次,如是则退出
                break;
            preFirstColi++;         //不是则更新起始位置
            i=preFirstColi;         //更新ij
            j=0;
        }else{                  //普通递增,则i-1, j+1
            i--;
            j++;
        }
    }

    for(int i=0; i<100; i++){       //打印
        for(int j=0; j<100; j++){
            if(matrix[i][j]==0)
                break;
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}


发表于 2023-02-14 16:02:54 回复(0)
#include <stdio.h>

int main() {
    int table[100][100]={1};//直接暴力拆解表格,然后根据要求进行输出
    //可以看到,对于第一行来说,an=a(n-1)+n;
    //第二行则是an=a(n-1)+n+1;
    //第三行是an=a(n-1)+n+2;
    //以此类推
    //第一列为bn=b(n-1)+n-1,依次确定初值。
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        if(i!=0)
            table[i][0]=table[i-1][0]+i;
        for(int j=0;j<n-i;j++){
            if(j!=0){
                table[i][j]=table[i][j-1]+(i+j+1);
                printf(" %d",table[i][j]);
            }
            else{
                printf("%d",table[i][j]);
            }
        }
        printf("\n");
    }
    return 0;

}

相比之下对于所有行同时找规律使用二维数组会比较麻烦一些,看到一个题解是对于逐行进行规律验证,先构建出第一行的初始值,然后按照每行分别找,这样会简单一些(因为只涉及一个变量的转换)
发表于 2023-01-01 15:33:41 回复(0)
#include <stdio.h>
int main(){
    int n;
    scanf("%d",&n);int m=1;int q=2;int p;
    for(int i=0;i<n;i++){
        p=i+1;m=q-1;//q用来记录上一行第二个数来确定本行第一个数,p为步长
        for(int j=0;j<n-i;j++){
            printf("%d ",m);
            if(j==1){
                q=m;
            }
            p++;m+=p;
        }
        printf("\n");
    }
} 

发表于 2022-05-27 19:07:41 回复(0)
#include <stdio.h>
#define suan(b) b*(b-1)/2+1
main(){
    int n,addu,count,sum;
    scanf("%d",&n);
    //第一层
    for(int i=1;i<=n;i++)
    {
        
        addu=i+1;
        count=1;
        sum=suan(i);
        printf("%d ",sum);
        for(int j=1;j<n+1-i;j++)
        {
            sum+=addu;
            printf("%d ",sum);
            addu++;
            if(count==n-i)
                printf("\n");
            count++;
        }
    }
    return 0;
}

发表于 2022-03-24 22:09:41 回复(0)
#include <stdio.h>
#define N 100

unsigned short arr[N][N] = {1};
main(){
    unsigned short n;
    while(scanf("%hu", &n)!=EOF){
        for(int i=0; i<n; ++i){
            for(int j=0; j<n-i; ++j){
                if(j==0) arr[i][0] = arr[i-1][0]+i;
                else arr[i][j] = arr[i][j-1]+i+j+1;
                printf("%hu ", arr[i][j]);
            }
            printf("\n");
        }
    }

}

发表于 2022-03-04 11:22:01 回复(0)