蛇形填数

顺时针将数字1,2,3,4,…,填入到给定大小的矩阵中,效果图如下:

新的思路

我觉得我以前的做法有点辣鸡,想了个新的写法:
把整个过程一圈一圈地来填,每一圈先后是从四个方向上去走step步:从左到右(LR),从上到下(UD),从右到左(RL),从下到上(DU)。
比如size=3时,step初始值为3-1=2,填完的矩阵如下:

1 2 3
8 0 4
7 6 5

可以发现,step每圈下来应该是减少2,而不是减少1!!!
而且在四个方向中自动转向,不需要检查边界,也不用等走过头再移动回来。
只是每圈过后都需要++x, ++y,哈哈,这是惯性。

还有注意最后step=1时,不应该继续进去了,因为没有四个位置可以走了,简单把那个位置赋值就好了(也就是上面的把8右边的0赋值为9)。

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

const int LR = 0, UD = 1, RL = 2, DU = 3;
int offset[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

typedef vector<vector<int> > Matrix;

void snackWalk(Matrix& m) {
    int x = 0, y = 0, step = m.size(), now = 1;
    while (--step > 0) {
        for (int dir = LR; dir <= DU; ++dir) {
            for (int i = 0; i < step; ++i) {
                m[x][y] = now++;
                x += offset[dir][0];
                y += offset[dir][1];
            }
        }
        ++x;
        ++y;
    }
    if (m[x][y] == 0)
        m[x][y] = now;
}

void display(const Matrix& m) {
    for (int i = 0; i < m.size(); ++i) {
        for (int j = 0; j < m[i].size(); ++j) {
            if (j < m[i].size()-1)
                cout << m[i][j] << ' ';
            else
                cout << m[i][j] << endl;
        }
    }
}

int main() {
    int N;
    cin >> N;
    if (N <= 0)
        return -1;
    Matrix m(N, vector<int>(N));
    snackWalk(m);
    display(m);

    return 0; 
}

旧的思路

模拟行走时,“方向数组”很好用,狂虐一堆if…else的写法:

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

const int LR = 0, UD = 1, RL = 2, DU = 3;
int dir_delta[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

inline bool checkBoundary(int x, int y, int ROW, int COL) {
    return x >= 0 && x < ROW && y >= 0 && y < COL;
}

vector<vector<int> > FillMatrix(int ROW, int COL) {
    int last_x = 0, last_y = -1, dir = LR, Size = ROW * COL;
    vector<vector<int> > ans(ROW, vector<int>(COL, -1));

    for (int i = 1; i <= Size; ++i) {
        int x = last_x + dir_delta[dir][0];
        int y = last_y + dir_delta[dir][1];
        if (checkBoundary(x, y, ROW, COL) && ans[x][y] == -1) {
            ans[x][y] = i;
            last_x = x;
            last_y = y;
        } else {
            --i;
            dir = (dir+1) % 4;
        }
    }

    return ans;
}

void display(vector<vector<int> >& matrix) {
    for (int i = 0; i < matrix.size(); ++i) {
        for (int j = 0; j < matrix[i].size(); ++j)
            cout << matrix[i][j] << '\t';
        cout << endl;
    }
}


int main() {
    vector<vector<int> > matrix = FillMatrix(4, 4);
    display(matrix);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值