蛇形填数
2016-04-09 20:12
176 查看
顺时针将数字1,2,3,4,…,填入到给定大小的矩阵中,效果图如下:
把整个过程一圈一圈地来填,每一圈先后是从四个方向上去走step步:从左到右(LR),从上到下(UD),从右到左(RL),从下到上(DU)。
比如size=3时,step初始值为3-1=2,填完的矩阵如下:
可以发现,step每圈下来应该是减少2,而不是减少1!!!
而且在四个方向中自动转向,不需要检查边界,也不用等走过头再移动回来。
只是每圈过后都需要++x, ++y,哈哈,这是惯性。
还有注意最后step=1时,不应该继续进去了,因为没有四个位置可以走了,简单把那个位置赋值就好了(也就是上面的把8右边的0赋值为9)。
新的思路
我觉得我以前的做法有点辣鸡,想了个新的写法:把整个过程一圈一圈地来填,每一圈先后是从四个方向上去走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; }
相关文章推荐
- 第一章 Activity的生命周期和启动模式
- 如何创建前台Android Service
- mysql忘记密码
- 吐槽
- POJ_3468_A Simple Problem with Integers_TLE
- 学习进度条(第六周)
- 团队介绍
- HDU5072 容斥原理
- 扩展型模式之Iterator(迭代器)模式
- hdu4864(贪心)
- keil中的数据类型
- DirectX SDK各版本下载地址备份
- stm32常见错误分析
- ModelDriven拦截器
- Dijkstra算法
- 屏幕适配(1)
- 17.合并两个排序的链表|剑指Offer
- XML CDATA
- 矩阵特征值分解与奇异值分解含义解析及应用
- Java笔试题(一)