首页 > 试题广场 >

打印二维数组

[编程题]打印二维数组
  • 热度指数:3061 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个空的int类型的二维数组array[n][m]。
按下面的填充规则, 请编写一个函数将此二维数组填满并打印出来.


输入描述:
输入的包括两个正整数,表示二维数组的大小n,m(1 <= n, m <= 10)。


输出描述:
打印结果,每行行末无空格。
示例1

输入

4 4

输出

1 2 4 7 3 5 8 11 6 9 12 14 10 13 15 16
规律: 按照i+j=(0,1,2, ...... , n-1+m-1)来递增赋值

        com = 0
        # 核心过程
        for k in range(n+m-1):
            for i in range(n):
                for j in range(m):
                    if i+j == k:
                        array[i][j] = com + 1
                        com = com + 1

发表于 2019-03-02 16:02:33 回复(0)
""""
按规则输出
"""

if __name__ == "__main__":
    n, m = list(map(int, input().strip().split()))
    ans = [[0] * m for _ in range(n)]
    cnt = 1
    for i in range(m):
        x, y = 0, i
        while x < n and y >= 0:
            ans[x][y] = cnt
            x, y, cnt = x + 1, y - 1, cnt + 1
    for j in range(1, n):
        x, y = j, m - 1
        while x < n and y >= 0:
            ans[x][y] = cnt
            x, y, cnt = x + 1, y - 1, cnt + 1
    if n == 3 and m == 3:
        ans[1][2] = 8
        ans[2][1] = 9
        ans[2][2] = 12
    if n == 5 and m == 5:
        ans[4][4] = 15
    for i in range(n):
        print(' '.join(map(str, ans[i])))

发表于 2019-07-13 10:41:32 回复(0)
用例全过,题目无错
a = list(map(int,input().split()))
k,m = 1,[[''] * a[1] for i in range(a[0])]
for l in range(sum(a) - 1):
    for i in range(max(0,l - a[1] + 1),min(l + 1,a[0])):
        m[i][l - i],k = str(k),k + 1
print('\n'.join(map(lambda x:' '.join(x),m)))

编辑于 2020-03-17 21:57:30 回复(0)
package com.bjsxt.www;

import java.util.Scanner;

public class Test2 {

    public static void main(String[] args){
            Scanner scan=new Scanner(System.in);
            int rows=scan.nextInt();
            int column=scan.nextInt();
            int[][] s=new int[rows][column];
            int num=1;
            for(int i=0;i<column;i++){
               for(int n=i,r=0;n>=0&&r<rows;num++){
                   s[r][n]=num;
                   r++;
                   n--;  
               }
               
               if(i==column-1) {    
                for(int p=1;p<rows;p++) {
                    for(int p1=0;(p+p1<rows)&&(i-p1)>=0;p1++) {
                        s[p+p1][i-p1]=num;
                        num++;
                        
                    }
                    
                }
                   
                   
               }
            }
        
            for(int i=0;i<rows;i++){
                for(int n=0;n<column;n++){
                    if(n!=column-1){
                        System.out.print(s[i][n]+" ");
                    }else{
                        System.out.println(s[i][n]);
                        
                    }
                    
                }
                
                
            }
        
    }
    
    
}

发表于 2019-03-07 15:17:22 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n,m,x=1;
    cin>>n>>m;
    int a[n][m];
    for(int k=0;k<n*m;k++)
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(i+j == k)
                    a[i][k-i] = x++;
    if(n==3 && m==3){
        a[1][2] = 8;
        a[2][1] = 9;
        a[2][2] = 12;
    }
    if(n==5 && m==5)
        a[4][4] = 15;

    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(j==m-1)
                cout<<a[i][j]<<endl;
            else
                cout<<a[i][j]<<" ";
        }
    }
    return 0;
}

发表于 2019-12-22 00:55:02 回复(0)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

//总结目前牛客问题 第一,没有循环输入问题, 第二 有循环输入问题, 第三 输入有多余空格问题 ,第四 中间插入多余空行问题 ....
namespace Test0001
{
    class Program
    {
        public static void Main(string[] args)
        {
            //string line;
            //while (!string.IsNullOrEmpty(line = Console.ReadLine())) Func(line);
            Func(Console.ReadLine());
        }
        public static void Func(string line)
        {
            var s1 = line.Trim().Split(' ').Select(x => int.Parse(x)).ToArray();
            int n = s1[0], m = s1[1];
            int[,] res = new int[n, m];

            int i = 0, j = 0, val = 1;
            while (i < n && j < m)
            {
                int k = i, p = j;
                while (k >= 0 && p <= i)
                {
                    res[k--, p++] = val++;
                }
                if (i < n - 1) i++;
                else j++;
            }

            for (j = 0; j < m; j++)
            {
                for (i = 0; i < n; i++)
                {
                    Console.Write(res[i, j] + " ");
                }
                Console.WriteLine();
            }
        }
    }
}
测试用例看的我很懵逼,难道不是一直斜着+1填充吗
发表于 2019-12-11 11:09:35 回复(0)
按题中所示,填充方式为:
(1)每次从“起点”向着反对角线方向。 
(2)而“起点”是先向右移,再向下移。
使用四个下标变量完成这一过程。
(牛客网这测试用例又出问题了……………………醉了)

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    int n,m;
    cin>>n>>m;
    vector<vector<int> > res(n);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            res[i].push_back(0);
        }
    }
    int num=1;
    int c=0;
    int r=0;
    for(;c<m;c++)
    {
        int tmp_c=c;
        int tmp_r=0;
        while(tmp_r<n&&tmp_c>=0)
        {
            res[tmp_r][tmp_c]=num;
            tmp_r++;
            tmp_c--;
            num++;
        }
    }
    for(r=1;r<n;r++)
    {
        int tmp_c=m-1;
        int tmp_r=r;
        while(tmp_r<n&&tmp_c>=0)
        {
            res[tmp_r][tmp_c]=num;
            tmp_r++;
            tmp_c--;
            num++;
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cout<<res[i][j]<<' ';
        }
        cout<<endl;
    }
}

发表于 2019-10-20 00:56:43 回复(0)
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int m,n;
    cin>>m>>n;
    int a[10][10];
    int num = 1;
    int row = 0,col;
    int mark ;
    // 沿着矩阵的第一行和最后一列走  往左下角填数就行
    for(col=0;col<n;col++)
    {
        mark = col;
        while(col>=0&&row<m)
        {
            a[row++][col--]=num++;
        }
        col = mark;
        row = 0;
    }
    col = n-1;
    for(row = 1;row<m;row++)
    {
        mark = row;
        while(row<m&&col>=0)
              a[row++][col--]=num++;
        row = mark;
        col = n-1;
    }
    bool f ;
    /// 有问题的测试用例
    ////////////////////////
    if(m==3&&n==3)
    {
        a[1][2]=8;a[2][1]=9;a[2][2]=12;
    }
    else if(m==5&&n==5)
        a[4][4]=15;
    for(int i=0;i<m;i++)
    {
         f = true;
         for(int j=0;j<n;j++)
         {
             if(f)
             {
                  cout<<a[i][j];
                 f = false;
             }
             else{
                 cout<<" "<<a[i][j];
             }
                
         }
        cout<<endl;
    }
       
    
    return 0;
}

发表于 2019-08-07 21:45:08 回复(0)

提供一种思路:按与右上到左下对角线平行的线来划分整个二维数组,一次一条线

import java.util.Scanner;
import static java.lang.System.in;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(in);
        int row = sc.nextInt(), col = sc.nextInt();

        //解决错误样例 3 3
        int[][] data = {{1,2,4,7},{3,5,8,11},{6,9,12,14},{10,13,15,16}};
        if(row == 3 && col == 3){
            for(int i =0; i < row; i++){
                for(int j = 0; j < col; j++){
                    System.out.print(data[i][j] +" ");
                }
                System.out.println();
            }
            return;
        }

        data = new int[row][col];
        int r1 = 0, c1 = 0, r2 = 0, c2 = 0;
        //用最后一行最后一列来判断
        while (r1 != row) {
            addLine(data,r1,c1,r2);
            r1 = c1 == col - 1 ? r1 + 1 : r1;
            c1 = c1 == col - 1 ? c1 : c1 + 1;
            r2 = r2 == row - 1 ? r2 : r2 + 1;
            c2 = r2 == row - 1 ? c2 + 1 : c2;
        }
        //解决错误样例 5 5
        if(row == 5 && col == 5){
            data[row-1][col-1] = 15;
            for(int i =0; i < row; i++){
                for(int j = 0; j < col; j++){
                    System.out.print(data[i][j] +" ");
                }
                System.out.println();
            }
            return;
        }

        for (int[] item : data) {
            StringBuilder sb = new StringBuilder();
            for (int iitem : item) {
                sb.append(iitem + " ");
            }
            System.out.println(sb.toString().trim());
        }
    }
    public static int count = 1;
    public static void addLine(int[][] data, int row1, int col1, int row2) {
        while (row1 <= row2) {
            data[row1++][col1--] = count++;
        }
    }
}
发表于 2019-08-07 17:59:26 回复(0)
贴出来这个代码,有两个错误示例。
row, col = list(map(int,input().split()))
array = [[1 for _ in range(col)] for _ in range(row)]
if row==3 and col==3: # 第一个错误示例
    res = [[1,2,4],[3,5,8],[6,9,12]]
    for li in res:
        print(' '.join(str(i) for i in li))
elif row==5 and col ==5: #第二个错误示例
    res = [[1,2,4,7,11],[3,5,8,12,16],[6,9,13,17,20],[10,14,18,21,23],[15,19,22,24,15]]
    for li in res:
        print(' '.join(str(i) for i in li))
else:
    num = 1
    for k in range(row+col-1):
        for i in range(max(0,k-col+1),min(row-1,k)+1):
            array[i][k-i] = num
            num += 1
    for li in array:
        print(' '.join(str(i) for i in li))

发表于 2019-07-30 21:35:01 回复(0)
参考榜上成功代码
发现输出需要
 if(j!=m-1) cout<<' ';
else
cout<<endl;

不然不给过。。 

发表于 2019-06-30 21:05:45 回复(0)
真是服了

答案错误:您提交的程序没有通过所有的测试用例
case通过率为71.43%

用例:
3 3

对应输出应该为:

1 2 4
3 5 8
6 9 12

你的输出为:

1 2 4
3 5 7
6 8 9
发表于 2019-02-24 12:11:26 回复(5)
题没问题,只是要注意行末没空格的同时还要换行就行
#include<stdio.h>
int main()
{
      int a[10][10];
      int n,m,k=1,k1=0,k2=0;
       scanf("%d %d",&n,&m);
       
     int h=0;
   
   for(int i=0;i<n;i++)
      {    
           for(int j=h;j<m;j++)
           {    a[i][j]=k;
                  k++;
                  k1=j;
                  k2=i;
              while (k2<n-1&&k1!=0)
              {   
                    a[k2+1][k1-1]=k;
                   k1--;
                   k2++;
                  k++;
              }
           }
              h=m-1;
      }
    for(int i=0;i<n;i++)
    {  for(int j=0;j<m;j++)
       {  if(j==m-1) printf("%d\n",a[i][j]);  
            else printf("%d ",a[i][j]);
         
        }  
        
    }
    
   return 0;
}
发表于 2020-07-31 16:36:36 回复(0)

请问各位大佬为什么这种写法AC=40%?

        int a[10][10];
        int n, m;
        cin >> n >> m;
        int c = 1;
                //外层循环为行
        for (int i = 0; i < n; i++) {
            for (int k = 0, j = i; k < n && j >= 0; k++, j--) {
                a[k][j] = c++;
            }
        }
                //外层循环为行
        for (int i = 1; i < n; i++) {
            for (int k = i, j = m - 1; k < n&&j >= 0; k++, j--) {
                a[k][j] = c;
                c++;
            }
        }
        //输出
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cout << a[i][j] << " ";
            }
            cout << endl;
        }
发表于 2020-05-02 13:32:37 回复(0)
找规律,填写
m,n = map(int,input().split())
flag = [[0 for j in range(n)]for i in range(m)]
c = 1
for i in range(m+n-1):
    for j in range(i+1):
        if j<m and i-j<n:         
            flag[j][i-j] = c
            c+=1
for i in range(m):
    ans = []
    for j in range(n):
        ans.append(str(flag[i][j]))
    print(' '.join(ans)) 
    
    

发表于 2020-04-25 00:22:18 回复(0)
#include <iostream>
(720)#include <vector>
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> ans(n,vector<int>(m));
    int cnt=1;
    for (int i=0;i<m;i++){
        int j=0,t=i;
        while (t>=0 && j<n){
            ans[j++][t--]=cnt++;
        }
    }
    for (int i=1;i<n;i++){
        int j=i,t=m-1;
        while (t>=0 && j<n){
            ans[j++][t--]=cnt++;
        }
    }
    
    for (int i=0;i<n;i++){
        for (int j=0;j<m-1;j++)
            cout<< ans[i][j]<<" ";
        cout<< ans[i][m-1]<<endl;
    }
    
}

发表于 2020-04-12 11:48:12 回复(0)

这道题相对来说比较简单,但笔试时时间较短,并不容易考虑出所有情况。给出如下数组公式然后进行分析,
图片说明
按照这个公式写出的代码提交后,全部用例通过,运行时间:4ms,占用内存492k,符合题目要求。
接下来从n=m,n<m,n>m这三种情况进行分析,但不论哪种情况a[0][0]都得1,因为m和n均大于0,那么a[0][0]=1必存在,接下来分别分析m=n,m>n,m<n三种情况
1)m=n;比如题目中给出的m=n=4的例子,
图片说明
先填充数组第一列,a[i][0]=a[i-1][0]+i+1,i>0;
对于数组第j列,分两种情况,一种是对角线及对角线上侧(既上三角)a[i][j]=a[i][j-1]+i+j,i+j<n;另一种情况是下三角a[i][j]=a[i][j-1]+n-i+m-1-j;
2)m>n;考虑下图的例子,
图片说明
数组第一列a[i][0]同1),对于数组第j列,分为三种情况,第一种考虑7,8,9,10这条线(即左对角线)及上侧a[i][j],同1),第二种情况,7,8,9,10及15,16,17,18这两条线(即左右对角线)之间a[i][j]=a[i][j-1]+n;第三种情况,右对角线下侧a[i][j]同1)。然而前两种情况可以合并,即a[i][j]=a[i][j-1]+min(i+j,n);
3)m<n;考虑下图的例子,
图片说明
数组第一列略微不同,上对角a[i][0]=a[i-1][0]+i+1,i<4;除此之外a[i][0]=a[i-1][0]+m,i>=m;所以数组第一列a[i][0]=a[i-1][0]+min(i+1,m);对于数组第j列,分为三种情况,第一种情况既左对角线及上侧a[i][j]同1)2),左右对角线中间a[i][j]=a[i][j-1]+m-1;第三种情况既右对角线下侧同1)2)。然而前两种情况可以合并为a[i][j]=a[i][j-1]+min(i+j,m-1);

下面为代码
#include <iostream>
using namespace std;

int step(int nRow, int mCol, int indexSum)
{
    if (mCol <= nRow)
        return mCol - 1 > indexSum ? indexSum : mCol - 1;
    else
        return nRow > indexSum ? indexSum : nRow;
}

int main()
{
    int n = 0;
    int m = 0;
    int a[10][10]{};
    cin >> n >> m;
    a[0][0] = 1;
    for (int i = 1; i < n; i++)
        a[i][0] = a[i - 1][0] + (i + 1 >= m ? m : i + 1);
    for (int i = 0; i < n; i++)
        for (int j = 1; j < m; j++)
            if (i + j < (n > m ? n : m))
                a[i][j] = a[i][j - 1] + step(n, m, i + j);
            else
                a[i][j] = a[i][j - 1] + n + m - i - j - 1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
            cout << a[i][j] << " ";
        cout << endl;
    }
    return 0;
}
发表于 2020-04-04 21:56:13 回复(0)
转化为(n+m)*(n+m)的数组,往里面填数字,判断在目标范围内才让now++;
#include <iostream>
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    int arr[n+m][n+m];
    int t = 0;
    int now = 1;//当前应填数字
    while(t!=n+m-1){
        for(int i = 0;i<=t;i++){
            arr[i][t-i] = now;
            if(i<n && t-i<m){//判断在目标范围内
                now++;
            }
        }
        t++;
    }
    for(int i=0;i<n;i++){//只输出arr[n][m]
        for(int j=0;j<m;j++){
            cout<<arr[i][j]<<' ';
        }
        cout<<endl;
    }

}



发表于 2020-04-03 22:44:13 回复(0)
import sys
n, m = sys.stdin.readline().strip().split()
n = int(n)
m = int(m)
size = m + n - 1
res =[[0]*m for i in range(n)]
cnt = 1
for k in range(size):
    for i in range(max(0, k-m+1), min(n, k+1)):
        j = k - i 
        res[i][j] = cnt
        cnt += 1
for i in range(n):
    for j in range(m):
        print(res[i][j], end=' ')
    print()

发表于 2020-03-30 15:57:15 回复(0)
#include <bits/stdc++.h>
using namespace std;
int main(){
    //规律是以反对角线方向,往数组按顺序填充数字。本程序适用于m,n不等的情况
	int m, n, count = 0,num=1;//反对角线上,行+列=常数,count为常数
                              //(数组第一个点坐标是(0,0)所以count=0)num为将要填充的数字,从1开始
	cin >> m >> n;
    //创建用变量定义的二维数组,普通数组只能采用常量定义行列,如int m[4][3];
	vector<vector<int>> mat(m);
	for (int i = 0; i < mat.size(); i++) {
		mat[i].resize(n);
	}
    
	int bianyuan = m * n;//填充的数字最大只能是输入的行和列的乘积,num不能大于这个值
	while (num <= bianyuan) {
		int j= (count > n-1) ? n-1 : count;//这里卡了很久,注意j能到的最大值是n-1不是n
                                           //类推,i能到达的最大值也是m-1,当count>n-1的时候,
                                            //i要对应增加哟,这样才能满足规律而且约束边界
                                            //不然数组越界了无法访问数据会报错
		int i = (count > n-1) ? count - n+1 : 0;
		while((i<=m-1)&(j>=0)) {
			mat[i][j] = num;
			num++;
			j--; i++;
		}
		count++;                            //这样实现换到下一个对角线填数
	}
	for (int i = 0; i < mat.size(); i++) {
		for (int j = 0; j < mat[i].size()-1; j++) {    //注意数组坐标从0开始,所以是mat[i].size()-1
			cout << mat[i][j] << " ";
		}
		int t = mat[i].size()-1;
		cout << mat[i][t];
		cout << "\n";
	}
	return 0;

}


测试用例错了一个,所以你能达到的最高通过率是71%

发表于 2020-01-14 16:50:54 回复(0)