寒假每日一题题解(1.11):蛇形矩阵

蛇形矩阵

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

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

输入格式

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

输出格式

输出满足要求的矩阵。

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

数据范围

1≤n,m≤1001≤n,m≤100

输入样例:
3 3
输出样例:
1 2 3
8 9 4
7 6 5

题解

#include <iostream>
#include <algorithm>
using namespace std;
int mat[105][105] = {0};
int main(){
    int n ,m;
    cin >> n >> m;
    /* 定义四个边界 */
    int left = 1;
    int right = m;
    int top = 1;
    int bottom = n;
    int cnt = 1;
    /* while循环判断是否结束 */
    while(left <= right && top <= bottom){
        for (int i = left ; i <= right ; i++){
            mat[top][i] = cnt++;
        }
        for (int i = top + 1 ; i <= bottom ; i++){
            mat[i][right] = cnt++;
        }
        for (int i = right - 1; i >= left && top < bottom; i--){
            mat[bottom][i] = cnt++;
        }
        for (int i = bottom - 1; i >= top + 1 && left < right ; i--){
            mat[i][left] = cnt++;
        }
        left++;
        right--;
        top++;
        bottom--;
    }
    for (int i = 1 ; i <= n ; i++){
        for (int j = 1 ; j <= m ; j++)
            cout << mat[i][j] << " ";
        cout << endl;
        
    }
    return 0;
}

暴力模拟

基本思路就是模拟,先用一个while循环判断做完没有
然后for循环:

  1. 填写第一行
  2. 填写最后一列
  3. 填写最后一行
  4. 填写第一列

ATTENTION:

  • 拐点处要考虑一下for的初始条件要不要加一
  • mat二维数组的行列不要搞错
  • 注意第三步和第四步!
    重点在于3和4步!!
    后面的&&跟上的内容是因为这不是一个方阵,因此会出现最后只剩一条竖线或者一条横线的情况
    于是他就会折返,往回填一串数(为什么只是一串?因为填了一串之后,例如在横线的情况下,top就大于bottom了,于是下次while循环就不进来了,竖线情况同理)

※(重点技巧)题解(二)(拐弯的常用技巧)

#include <iostream>
#define N 10005
using namespace std;

int res[N][N];
int main(){
    int n ,m , d = 0 , x = 0 , y = 0;
    int dx[] = {-1,0,1,0}; int dy[] = {0,1,0,-1};
    cin >> n >> m ;
    for (int i = 1 ; i <= m * n ; i++){
        res[x][y] = i;
        int a = x + dx[d] , b = y + dy[d];//a,b作为【探险变量】,去下一个位置【试探】
        if (a >= n || a < 0 || b >= m || b < 0 || 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;
}

思路:

利用一个数组(或者说矢量)的方法来实现旋转方向的作用

int dx[] = {-1,0,1,0}; int dy[] = {0,1,0,-1};

配合int d,d为0,1,2,3分别是左、上、右、下。

结合试探变量a和b

注意,这里都在以x和y为【中心】求试探变量,试探不成功则【围绕x和y】再展开试探,最后,一定要让试探的小弟带大哥x和y前进(即更新变量x和y),中途都是在试探,不要变x和y,不然这里没有试探好,中心就移动了,会很麻烦!!

 int a = x + dx[d] , b = y + dy[d];//a,b作为【探险变量】,去下一个位置【试探】

试探失败该干啥?

【围绕x和y】这个【中心】【换个方向】【试探】

d = (d + 1) % 4;

(上面就是换方向的方法)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值