首页 > 试题广场 >

蛇形矩阵

[编程题]蛇形矩阵
  • 热度指数:180592 时间限制: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}
0.5*(x+y+1)(x+y+2)-y
发表于 2022-05-20 11:12:29 回复(0)
发表于 2022-05-03 17:13:59 回复(1)
问题不复杂可以尝试几种方式做:
1.像蛇形走位一样将数值放入数组,比较好理解
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int[][] arr = set(n);
        //System.out.println(n);
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<n; i++){
            for(int j=0; j<n-i; j++){
                sb.append(arr[i][j]).append(" ");
            }
            sb.append("\r\n");
        }
        System.out.println(sb.toString());
        br.close();
    }
    
    public static int[][] set(int n){
        int[][] arr = new int[n][n];
        int y=0, m=0;//y为横坐标,m表示坐标上的值
        for(int i=0; i<n; i++){//i为斜着的行
            y = i;
            while(y>=0){
                arr[y][i-y] = ++m;
                y--;
            }
        }
        return arr;
    }
    
}
2.硬方法,线下计算得出坐标公式,求公式比较难
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();
        int number = 0;
        for(int x=1; x<=n; x++){//横坐标x
            for(int y=1; y<=n-x+1; y++){//纵坐标y
                //线下计算得出坐标公式
                number = (x*x + y*y -y -3*x)/2 + x*y + 1;
                sb.append(number).append(" ");
            }
            sb.append("\r\n");
        }
        System.out.println(sb.toString());
        br.close();
    }
}
3.定义一个横向步长(x+y+1)和一个纵向步长(x),每一行计算后接着计算下一行
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();
        int base = 1;//每一行的初始值
        for(int x=0; x<n; x++){//横坐标x,从0开始
            base += x;//初始值累积
            int number = base;//坐标值
            for(int y=0; y<n-x; y++){//纵坐标y,从0开始
                if(y>0){
                    number += x+y+1;//x+y+1为横坐标步长
                }
                sb.append(number).append(" ");
            }
            sb.append("\r\n");
        }
        System.out.println(sb.toString());
        br.close();
    }
}




发表于 2022-04-22 15:38:25 回复(0)
第一行[1 3 6 10]依次相加 2 3 4
第二行[2 5 9]     依次相加    3 4
第三行[4 8]        依次相加       4
第四行[7]           依次相加
每行第一个依次相加1 2 3 ...
a = int(input())
for i in range(1, a + 1):
    num = 1 + sum(range(i))
    for j in range(1 + i, a + 2):
        print(num, end=' ')
        num = num + j
    print()
发表于 2022-03-28 17:54:58 回复(0)
num = int(input())
#dic = {}
first = 1
for i in range(0,num):
    li = []
    first = first + i
    li.append(str(first))
#    print(first, end = " ")
    val = first
    for j in range(i+2, num+1):
        val = val + j
        li.append(str(val))
        #       print(val, end = " ")
#   print(li)
    print(" ".join(li))

发表于 2022-03-23 10:38:07 回复(1)
while True:
    try:
        n=int(input())
        for i in range(n):
            an=int(1+i*(i+1)/2)
            p=2
            for j in range(n-i):
                print(an,end=' ')
                x=i+p
                an=an+x
                p+=1
            print()
    except:
        break

发表于 2021-12-19 22:05:02 回复(0)
没找到通项公式,所以干脆用递推公式,因为是嵌入式出身,比较舍不得用内存,所以就用了一行的buffer。
#include <stdio.h>

int iLineBuff[101];

void genFirstLine(int *buf, int len)
{
    int i;
    int temp = 0;
    for(i=1;i<=len;++i)
    {
        buf[i] = i * i - temp;
        temp = buf[i];
    }
}
void printTriangle(int *buff, int len)
{
    int i, j;
    for(i=1;i<=len;++i)
    {
        for(j=i;j<=len;++j)
        {
            printf("%d ", buff[j]--);
        }
        printf("\n");
    }
}

int main()
{
    int len;
    while(EOF != scanf("%d", &len))
    {
        genFirstLine(iLineBuff, len);
        printTriangle(iLineBuff, len);
    }
    return 0;
}


发表于 2021-09-17 23:07:17 回复(0)
while True:
    try:
        a =int(input())

        b = []
        s = 0
        for i in range(0,a+1):
            b.append([])
            for j in range(0,i):
                s+=1
                b[i].append(s)
        b = b[1::]


        
        for i in range(a):
            for j in range(i,a): #(0,3)  (1,3) (2,3) (3)
                print(b[j][j-i],end=' ')
            print()  
    except:
        break


发表于 2021-09-12 15:12:37 回复(0)
#include <bits/stdc++.h>
using namespace std;


int main(){
    /*
    蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。
    例如,当输入5时,应该输出的三角形为:
    1 3 6 10 15
    2 5 9 14
    4 8 13
    7 12
    11
    */
    /*  N = 5
    第一行,依次+2 +3 +4 +5
    第二行,依次+3 +4 +5
    第三行,依次+4 +5
    第四行,+5
    第五行,第四行最后一个减1
    每排开头的第一个 等于 上一排第二个减一
    */
    //可以创建一个二维数组,i为行数,每行第二个数为  第一个数+i+1,
    int inputNum;
    while(cin >> inputNum){
        vector<vector<int>> vec;
        vec.resize(inputNum);//初始化二维数组的行数
        int i = 0 , n = inputNum;
        int num = 1;
        while(n > 0){
            for(int j = i + 1; j <= inputNum; j++){//插入一行数组
                vec[i].push_back(num);
                num = num + j + 1;
            }
            i++;//控制数组插入行数
            n--;
            num = vec[i - 1][1] - 1;
        }
        for(int f = 0; f < inputNum; f++){
            for(int t = 0; t < vec[f].size(); t++){
                cout << vec[f][t] << " ";
            }
            cout << endl;
        }
    }
    return 0;
}

发表于 2021-09-02 13:42:08 回复(0)
#include<iostream>
#include<vector>
using namespace std;

int main(){
    int n;
    while(cin>>n){
        vector<vector<int>>snake(n,vector<int>(n,0));
        //初始化第一行
        for(int i=0;i<n;i++){
            snake[0][i]=(i+1)*(i+2)/2;
        }
        //递推
        for(int i=1;i<n;i++){
            for(int j=0;j<n-i;j++){
                snake[i][j]=snake[i-1][j+1]-1;
            }
        }
        //输出
        for(int i=0;i<n;i++){
            for(int j=0;j<n-i;j++){
                cout<<snake[i][j]<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}

发表于 2021-08-16 14:55:30 回复(0)
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNextInt()){
            int n = in.nextInt(), a = 0, k = 1;
            for(int i=1;i<=n;i++){
                k += i-1;
                a = k;
                System.out.print(a+" ");
                for(int j=1,k2=1+i;j<=n-i;j++){  // 注意:j<=n-i是使每行输出的个数递减,k2=1+i是每行的初始都会加1
                    a += (k2++);
                    System.out.print(a+" ");
                }
                System.out.println();
            }
        }
    }
}

发表于 2021-08-11 23:19:49 回复(0)
这个题需要找到首列元素和每一行元素之间的规律,之后就好写了
import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int lines = 0;

        while (scanner.hasNext()){
            lines = scanner.nextInt();
            printSnakeNum(lines);
        }
    }

    public static void printSnakeNum(int lines){
        int head = 1;    // 从 1 开始
        for (int i = 0; i < lines; i++){
            head += i;    // 首列元素之间相差 1 2 3 4.... 以此类推
            System.out.print(head + " ");
            int body = head;
            for (int j = i + 2; j <= lines; j++){    // 第一行元素从2相差开始递增,第二行从3开始递增,每一行都比上一行的差值增1
                body += j;
                System.out.print(body + " ");
            }
            System.out.println();
        }
    }
}


发表于 2021-08-06 16:11:20 回复(0)
#include <stdio.h>
#include <stdlib.h>

#define N 100

int mat[N][N];

int main(void) {
  int n, i, j, k, num;
  while (scanf("%d", &n) != EOF) {
    num = 1;
    for (k = 0; k < n; ++k)
      for (i = k, j = 0; i >= 0; --i, ++j)
        mat[i][j] = num++;
    
    for (i = 0; i < n; ++i) {
      for (j = 0; j < n - i; ++j)
        printf("%d ", *(*(mat + i) + j));
      putchar('\n');
    }
  }
  return 0;
}

发表于 2021-07-06 19:25:46 回复(0)
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
int main()
{
    int n;
    while(cin>>n) {
        vector<vector<int>> matrix;
        int id=1;
        n=(1+n)*n/2; //输出的数字总数
        while(id<=n) {
            matrix.push_back(vector<int>(1,id++));
            int div=matrix.size();
            div-=1;
            while(--div>=0) {
                matrix[div].push_back(id++);
            }
        }
        for(int i=0;i<matrix.size();++i) {
            for(int x:matrix[i]) {
                cout<<x<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}
发表于 2021-06-26 11:41:19 回复(0)
 public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            int num = in.nextInt();
            //记录所有行第一个元素的值
            int[] first = new int[num];
            first[0] = 1;
            for(int i = 0;i < num;i++){
                if(i > 0){
                    first[i] = first[i - 1] + i;
                }
                //记录这一行的值
                int[] rows = new int[num - i];
                rows[0] = first[i];
                for(int j = 0;j < num - i;j++){
                    if(j > 0){
                        //找规律,该值与i和j都有关系
                        rows[j] = rows[j - 1] + i + j + 1; 
                    }
                    System.out.print(rows[j] + " ");
                }
                System.out.println();
            }
        }
    }
发表于 2021-04-14 16:03:32 回复(0)
其实是有规律的
(1) 对于行:第一行第一个数为1,之后每行的第一个数按照增幅1,2,3,4,...进行变化。
(2) 对于列:每列的数以该行的第一个数为基准,也是按照有规律的增幅进行变化,第i行的初始增幅为i+1,往后的增幅每列自增1。
(3) 第一行n个数,第二行n-1个数,......
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while((line = br.readLine()) != null){
            int N = Integer.parseInt(line.trim());
            int rowBeginNum = 1;           // 第一行的第一个数
            int stepRow = 1;               // 每行第一个数的增幅
            for(int i = 1; i <= N; i++){
                int row = rowBeginNum;     // 每行的第一个数
                int n = N - i + 1;         // 每行的数个数
                StringBuilder sb = new StringBuilder();
                int stepCol = i + 1;       // 每列的初始增幅
                int count = 0;
                while(count++ < n){
                    sb.append(row + " ");
                    row += stepCol;        // 更新本行的下一个数
                    stepCol ++;            // 更新每列数的增幅
                }
                rowBeginNum += stepRow;    // 更新下一行的第一个数
                stepRow ++;                // 更新每行第一个数的增幅
                System.out.println(sb.toString().trim());
            }
        }
    }
}
发表于 2021-03-22 16:28:15 回复(0)
//试了下竟然通过了!!!
#include <iostream>
using namespace std;

int main()
{
    int n;
    while(cin >> n)
    {
        int a[100][100] = {0};
        int b[100] = {0};
        int t1 = 1;
        for(int i = 0; i < n; i++)
        {
            for(int j = i; j >= 0; j--)
            {
                a[j][b[j]] = t1;
                b[j]++;
                t1++;
            }
        }
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < b[i]; j++)
            {
                cout << a[i][j] << " ";
            }
            cout << endl;
        }
    }
}

发表于 2021-03-10 22:29:30 回复(3)
while True:
    try:
        n=int(input())
        lst=[]
        for i in range(n):
                lst.append([ii for ii in range(int(i*(i+1)/2+1),int((i+1)*(i+2)/2+1))])
        m=0
        for m in range(n):
            for i in range(m,n):
                print(lst[i][-m-1],end=' ')
            print('')
    except:
        break

发表于 2021-01-03 17:38:40 回复(0)
#include <stdio.h>

int main()
{
    int n;
    int func(int m,int n);
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;i+j<n;j++)
            {
                printf("%d ",func(i,j));
            }
            printf("\n");
        }
    }
    return 0;
}
int func(int m,int n)
{
    if(m==0&&n==0)return 1;
    else if(m!=0&&n==0)return func(m-1,n)+m;
    else return func(m,n-1)+m+n+1;
}
递归居然要5ms。
发表于 2020-09-29 23:25:31 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()){
            Main a = new Main();
            int n = scanner.nextInt();
            String result = "";
            int start = 1;
            for (int i = 0; i < n; i++){
                result += String.valueOf(start);
                int current = start;
                int count = 2+i;
                while (count <= n){
                    result += " " + String.valueOf(current+count);
                    current = current+count;
                    count += 1;
            }
                result += "\n";
                start += 1+i;
            }
            System.out.print(result);
        }
    }
}

编辑于 2020-09-23 21:01:55 回复(0)