【2022.12.10每天四个简单题之简单题大智慧系列4】(平方矩阵 I ,平方矩阵 II ,平方矩阵 III , 蛇形矩阵 )

今天继续来看数组中的题目

平方矩阵 I

输入整数 N,输出一个 N 阶的回字形二维数组。

数组的最外层为 1,次外层为 2,以此类推。

输入格式
输入包含多行,每行包含一个整数 N。

当输入行为 N=0 时,表示输入结束,且该行无需作任何处理。

输出格式
对于每个输入整数 N,输出一个满足要求的 N 阶二维数组。

每个数组占 N 行,每行包含 N 个用空格隔开的整数。

每个数组输出完毕后,输出一个空行。

数据范围
0≤N≤100
输入样例:
1
2
3
4
5
0
输出样例:
1

1 1
1 1

1 1 1
1 2 1
1 1 1

1 1 1 1
1 2 2 1
1 2 2 1
1 1 1 1

1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1

看到这个题,首先,我们需要输入一个数n,并创建横n行纵n列的一个二维矩阵

第一种做法(无脑循环)

我们可以一次一次的循环,先让cnt=1;循环一周后再让cnt++即可
代码:

#include<cstdio>
using namespace std;
int main()
{
    while(1){
        int n,cnt=1,m,k,i,j;
        scanf("%d",&n);
        int a[n][n]={0};
        if(n==0){
            break;
        }
        for( m=0,k=n-1;m<=k;m++,k--){
            for( i=m,j=m;j<=k;j++){
                a[i][j]=cnt;
            }
            for( i=m,j=k;i<=k;i++){
                a[i][j]=cnt;
            }
            for( i=k,j=k;j>=m;j--){
                a[i][j]=cnt;
            }
            for( i=k,j=m;i>=m;i--){
                a[i][j]=cnt;
            }
            cnt++;
        }
        
        for(int p=0;p<n;p++){
            for(int q=0;q<n;q++){
                printf("%d ",a[p][q]);
            }
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

第二种做法(找规律)

可以发现,每个地方填什么值取决于他到上下左右边界的距离的最小值
故而给我们一个i,j(横行与纵行)后我们只需要看它到上下左右边界的最小值即可
上:i
下:n-i+1
左:j
右:n-j+1
代码如下:

#include <iostream>

using namespace std;

int main()
{
    int n;
    while (cin >> n, n)
    {
        for (int i = 1; i <= n; i ++ )
        {
            for (int j = 1; j <= n; j ++ )
            {
                int up = i, down = n - i + 1, left = j, right = n - j + 1;
                cout << min(min(up, down), min(left, right)) << ' ';
            }
            cout << endl;
        }

        cout << endl;
    }

    return 0;
}


平方矩阵 II

输入整数 N,输出一个 N 阶的二维数组。

数组的形式参照样例。

输入格式
输入包含多行,每行包含一个整数 N。

当输入行为 N=0 时,表示输入结束,且该行无需作任何处理。

输出格式
对于每个输入整数 N,输出一个满足要求的 N 阶二维数组。

每个数组占 N 行,每行包含 N 个用空格隔开的整数。

每个数组输出完毕后,输出一个空行。

数据范围
0≤N≤100
输入样例:
1
2
3
4
5
0
输出样例:
1

1 2
2 1

1 2 3
2 1 2
3 2 1

1 2 3 4
2 1 2 3
3 2 1 2
4 3 2 1

1 2 3 4 5
2 1 2 3 4
3 2 1 2 3
4 3 2 1 2
5 4 3 2 1
首先,我们还是先整出来n个二维数组,然后我们可以先将他的对角线部分全部设为1

while(cin>>n,n){
        int a[n][n];
        for(int i=0;i<n;i++){
            a[i][i]=1;
            //......
            }
}

然后我们可以发现,剩下的每个地方的值就等于其到达对角线的距离+对角线上的值(也就是1)
我们先写行,也就是

//......
for(int i=0;i<n;i++){
            a[i][i]=1;
            for(int j=i+1,k=2;j<n;j++,k++){
                a[i][j]=k;
            }
            //......

然后我们再写列

//.......
for(int j=i+1,k=2;j<n;j++,k++){
                a[j][i]=k;
            }
        }
        //......

总的来说,可以理解为这样填:
在这里插入图片描述
最后附上代码:

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
int main()
{
    int n;
    while(cin>>n,n){
        int a[n][n];
        for(int i=0;i<n;i++){
            a[i][i]=1;
            for(int j=i+1,k=2;j<n;j++,k++){
                a[i][j]=k;
            }
            for(int j=i+1,k=2;j<n;j++,k++){
                a[j][i]=k;
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                printf("%d ",a[i][j]);
            }
            printf("\n");
        }
        printf("\n");
    }
     
    return 0;
}

平方矩阵 III

输入整数 N,输出一个 N 阶的二维数组 M。

这个 N 阶二维数组满足 M[i][j]=2i+j。

具体形式可参考样例。

输入格式
输入包含多行,每行包含一个整数 N。

当输入行为 N=0 时,表示输入结束,且该行无需作任何处理。

输出格式
对于每个输入整数 N,输出一个满足要求的 N 阶二维数组。

每个数组占 N 行,每行包含 N 个用空格隔开的整数。

每个数组输出完毕后,输出一个空行。

数据范围
0≤N≤15
输入样例:
1
2
3
4
5
0
输出样例:
1

1 2
2 4

1 2 4
2 4 8
4 8 16

1 2 4 8
2 4 8 16
4 8 16 32
8 16 32 64

1 2 4 8 16
2 4 8 16 32
4 8 16 32 64
8 16 32 64 128
16 32 64 128 256
我们可以看出,这个好像是与平方有关系,那他和i,j(也就是横行与列行)有什么关系呢?我们可以发现,比如第一排:
在这里插入图片描述
故而我们可以发现,每一个位置填那个数字,就等于2的i+j的平方,也就是2的它们所在的行数加上列数方
故而我们可以写出以下代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
    int n;
    while(cin>>n,n){
        int a[n][n]={0};
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                a[i][j]=pow(2,i+j);
            }
        }
            
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    printf("%d ",a[i][j]);
                }
                printf("\n");
            }
            printf("\n");
        }
        
    
    return 0;
}

蛇形矩阵

输入两个整数 n 和 m,输出一个 n 行 m 列的矩阵,将数字 1 到 n×m 按照回字蛇形填充至矩阵中。

具体矩阵形式可参考样例。

输入格式
输入共一行,包含两个整数 n 和 m。

输出格式
输出满足要求的矩阵。

矩阵占 n 行,每行包含 m 个空格隔开的整数。

数据范围
1≤n,m≤100
输入样例:
3 3
输出样例:
1 2 3
8 9 4
7 6 5
是一个长方形的不是正方形的!!!
在这里插入图片描述

此题我们可以用到偏移量
数组的偏移量用坐标来表示

在这里插入图片描述
先将四个方向定义一下,然后先从右开始走,然后发现撞墙了就换个方向走,共走n*m个格子
撞墙条件:
1.出界
2.重复,走到之前走过的位置
定义四个方向:

int dx[]={0,1,0,-1},dy[]={1,0,-1,0};//初始化无须定义长度

定义一个变量k值为每个数组位置上的值
判断有没有撞墙

if(a<0||a>=n||b<0||b>=m||res[a][b])//最后的意思是那个位置上有数不为零

如果撞墙的话就90度旋转

if(a<0||a>=n||b<0||b>=m||res[a][b]){
            d=(d+1)%4;//d指的是偏移量数组的下标,这样可以控制向哪个方向走
            a=x+dx[d],b=y+dy[d];
        }

代码实现:

#include<iostream>
using namespace std;
int res[100][100];
int main()
{
    int n,m;
    cin>>n>>m;
    int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
    for(int x=0,y=0,k=1,d=0;k<=n*m;k++){
        res[x][y]=k;
        int a=x+dx[d],b=y+dy[d];
        if(a<0||a>=n||b<0||b>=m||res[a][b]){
            d=(d+1)%4;
            a=x+dx[d],b=y+dy[d];
        }
        x=a,y=b;//完成赋值后x,y分别向后按计划移动一格
    }
    for (int i = 0; i < n; i ++ )
    {
        for (int j = 0; j < m; j ++ ) cout << res[i][j] << ' ';
        cout << endl;
    }
    return 0;
}

希望对大家有所帮助!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想进步的22级本科生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值