C/C++面试(3)——矩阵编程题(模拟法)
2015-10-24 14:31
696 查看
谈谈机试吧,虽然一举通过某知名学府的机试获得预录取,但是之后找实习过程中的机试通过率只有10%,十分惭愧。所以特地开了编程版,之后继续有彩蛋(⊙o⊙)哦~
链接里面有很多种方法,在这里,我只提出一种方法,只要稍加改动,就可以解决螺旋矩阵和回字矩阵了,具有一定的通用性吧。
相关链接:/article/7918019.html
Tips:一圈一圈地由内向外拓展
1.1.2从外向内螺旋矩阵:
1 按顺时针方向构建一个m * n的螺旋矩阵(或按顺时针方向螺旋访问一个m * n的矩阵):
2 在不构造螺旋矩阵的情况下,给定坐标i、j值求其对应的值f(i, j)。
比如对11 * 7矩阵, f(6, 0) = 27 f(6, 1) = 52 f(6, 3) = 76 f(6, 4) = 63
Tips:一圈一圈地由外向内走
双螺旋矩阵的定义如下,矩阵的最中心是1,往上是2,右拐3,向下4,然后依次5、6,7...构成一条顺序增大的螺旋线,此外,如果从中心往下走的话,也是一条对称的螺旋线。题目是给定一个矩阵维度N,将其打印出来,示例如下。要求在纸上把代码写完整,时间半小时左右。
25 14 15 16 17 18 19
24 13 6 7 8 9 20
23 12 5 2 3 10 21
22 11 4 1 4 11 22
21 10 3 2 5 12 23
20 9 8 7 6 13 24
19 18 17 16 15 14 25
只要从(0,0)开始,一圈一圈往里走就行了,再根据对称,把另一半也算出来。
总结:其实就是一圈一圈地由内向外或者由外向内走来模拟这个矩阵的形成。
打印出如下格式的数据:
我自己用模拟法写的:该办法一不小心就会出错(⊙o⊙)哦~
原文链接http://blog.163.com/lvan100@yeah/blog/static/6811721420107176921749/
解题思路:
如果我们将矩阵变一下形状,如下:
这样就变成输出一个三角阵了,简单多了。只是呢,需要在某些行上做一些逆序变换。
奇数 时变换奇数行; 偶数时变换偶数行。
最后按照斜线将数填入原来矩阵中,OK!
链接里面有很多种方法,在这里,我只提出一种方法,只要稍加改动,就可以解决螺旋矩阵和回字矩阵了,具有一定的通用性吧。
1.螺旋矩阵
Tips:考虑到这是机试,时间有限,并不排除思维比较活跃的童鞋能够马上找到坐标与数值的关系,但是“模拟法”是最快最直接的。相关链接:/article/7918019.html
1.1单螺旋矩阵
1.1.1从中间往外顺时针旋转,如下所示:Tips:一圈一圈地由内向外拓展
#include <iostream> using namespace std; int main() { int r, c; cin >> r >> c; int **a = new int*[r]; for (int k = 0; k < r; k ++) a[k] = new int[c]; int col = (c + 1)/2, row = (r + 1)/2; //3,3 int end = (c - 1) / 2; //2 int num = 1; a[col-1][row-1] = num ++; int idx, i, j; for (idx = end; idx > 0; idx --){ for (i = idx; i <= row; i ++) //2,3 a[i][col] = num ++; for (j = col -1; j >= idx - 1; j --)//2,1 a[row][j] = num ++; for (i = row - 1; i >= idx - 1; i --)//2,1 a[i][idx - 1] = num ++; for (j = idx; j <= col; j ++)//2,3 a[idx - 1][j] = num ++; col ++; row ++; } for (i = 0; i < r; i ++){ for (j = 0; j < c; j ++) cout << a[i][j] << ' '; cout << endl; } for(i = 0; i < r; i++){ delete []a[i]; a[i] = NULL; } delete []a; a = NULL; return 0; }
1.1.2从外向内螺旋矩阵:
1 按顺时针方向构建一个m * n的螺旋矩阵(或按顺时针方向螺旋访问一个m * n的矩阵):
2 在不构造螺旋矩阵的情况下,给定坐标i、j值求其对应的值f(i, j)。
比如对11 * 7矩阵, f(6, 0) = 27 f(6, 1) = 52 f(6, 3) = 76 f(6, 4) = 63
Tips:一圈一圈地由外向内走
#include <iostream> using namespace std; int main() { int r, c; cin >> r >> c; int **a = new int*[r]; for (int k = 0; k < r; k ++) a[k] = new int[c]; int col = c - 1, row = r - 1; int side = col < row ? col : row; int end = (side + 1) / 2; int idx, i, j, num = 1; for (idx = 0; idx <= end; idx ++){ for (j = idx; j <= col; j ++) //一定为j <= col,不然最中间就没被赋值了 a[idx][j] = num ++; for (i = idx+1; i < row; i ++) //一定为i = idx+1,而不是i=idex,否则a[idx][col]会被赋两次值 a[i][col] = num ++; for (j = col; j > idx; j --) a[row][j] = num ++; for (i = row; i > idx; i --) a[i][idx] = num ++; col --; row --; } for (i = 0; i < r; i ++){ for (j = 0; j < c; j ++) cout << a[i][j] << ' '; cout << endl; } for(i = 0; i < r; i++){ delete []a[i]; a[i] = NULL; } delete []a; a = NULL; return 0; }
1.2双螺旋矩阵
题目描述如下:双螺旋矩阵的定义如下,矩阵的最中心是1,往上是2,右拐3,向下4,然后依次5、6,7...构成一条顺序增大的螺旋线,此外,如果从中心往下走的话,也是一条对称的螺旋线。题目是给定一个矩阵维度N,将其打印出来,示例如下。要求在纸上把代码写完整,时间半小时左右。
25 14 15 16 17 18 19
24 13 6 7 8 9 20
23 12 5 2 3 10 21
22 11 4 1 4 11 22
21 10 3 2 5 12 23
20 9 8 7 6 13 24
19 18 17 16 15 14 25
只要从(0,0)开始,一圈一圈往里走就行了,再根据对称,把另一半也算出来。
#include <iostream> using namespace std; int dx[4] = {1, 0, -1, 0}; int dy[4] = {0, 1, 0, -1}; int main() { int n; cin >> n; int **a = new int* ; for (int k = 0; k < n; k ++) a[k] = new int ; int num = (n * n + 1) / 2; int x = 0, y = 0, dir = 0; int side = n - 1, tmp = n - 1, cnt = 0; while(num){ a[x][y] = a[n - x - 1][n - y - 1] = num; x += dx[dir]; y += dy[dir]; num --; cnt ++; if (cnt == side){ if ((dir % 2) == 0){ if (side == tmp) side --; else side -= 2; } cnt = 0; dir = (dir + 1) % 4; } } for (int i = 0; i < n; i ++){ for (int j = 0; j < n; j ++) cout << a[i][j] << '\t'; cout << endl; } for(i = 0; i < n; i++){ delete []a[i]; a[i] = NULL; } delete []a; a = NULL; return 0; }
2.回形矩阵
Tips:其实是不是很像从外向内螺旋矩阵呢?只要稍加改动就好~\(≧▽≦)/~啦啦啦11111 12221 12321 12221 11111
#include <iostream> using namespace std; int main() { int r, c; cin >> r >> c; int **a = new int*[r]; for (int k = 0; k < r; k ++) a[k] = new int[c]; int col = c - 1, row = r - 1; int side = col < row ? col : row; int end = (side + 1) / 2; int idx, i, j, num = 0; for (idx = 0; idx <= end; idx ++){ num ++; //改动在这里 for (j = idx; j <= col; j ++) a[idx][j] = num; for (i = idx+1; i < row; i ++) a[i][col] = num; for (j = col; j > idx; j --) a[row][j] = num; for (i = row; i > idx; i --) a[i][idx] = num; col --; row --; } for (i = 0; i < r; i ++){ for (j = 0; j < c; j ++) cout << a[i][j] << ' '; cout << endl; } for(i = 0; i < r; i++){ delete []a[i]; a[i] = NULL; } delete []a; a = NULL; return 0; }
总结:其实就是一圈一圈地由内向外或者由外向内走来模拟这个矩阵的形成。
3.蛇形矩阵
题目描述:打印出如下格式的数据:
我自己用模拟法写的:该办法一不小心就会出错(⊙o⊙)哦~
#include<iostream> using namespace std; int main(void) { int n, i; cin >> n; //n为奇数 int **a = new int* ; for (i = 0; i < n; i ++) a[i] = new int ; int x = 0, y = 0; i = 1; a[0][0] = i; while (x == 0 && (++ y) <= n-1){ a[x][y] = ++ i; while (y >= 1 && x <= n - 1) a[++ x][-- y] = ++ i; a[++ x][y] = ++i;//重要!!! while (x >= 1) a[-- x][++ y] = ++ i; } y = n - 1; int max = n*n; while (y == n-1 && x < n-1){ a[++ x][y] = ++ i; while (x < n - 1 && y > 0) a[++ x][-- y] = ++ i; a[x][++ y] = ++ i;//重要!!! while (y < n - 1) a[-- x][++ y] = ++ i; } int j; for (i = 0; i < n; i ++){ for (j = 0; j < n; j ++) cout << a[j][i] << ' '; cout << endl; } for (i = 0; i < n; i ++){ delete []a[i]; a[i] = NULL; } delete []a; a = NULL; return 0; }比较巧妙的办法:
原文链接http://blog.163.com/lvan100@yeah/blog/static/6811721420107176921749/
解题思路:
如果我们将矩阵变一下形状,如下:
这样就变成输出一个三角阵了,简单多了。只是呢,需要在某些行上做一些逆序变换。
奇数 时变换奇数行; 偶数时变换偶数行。
最后按照斜线将数填入原来矩阵中,OK!
</pre></div><pre name="code" class="cpp">#include<iostream> using namespace std; int main(void) { int n, i; cin >> n; //n为奇数 int size = 2 * n - 1, j; int **p = new int*[size]; for (i = 0; i < size; i ++){ p[i] = new int ; } int **a = new int* ; for (i = 0; i < n; i ++){ a[i] = new int ; } //三角形数阵 int num = 1; for (i = 0; i <= n - 1; i ++){ for (j = 0; j <= i; j ++) p[i][j] = num ++; } for (i = n; i < size; i ++){ for (j = 0; j < size - i; j ++) p[i][j] = num ++; } //逆序变换 int tmp = 1; for (i = 1; i <= n - 1; i += 2){ for (j = 0; j <= i/2; j ++){ tmp = p[i][j]; p[i][j] = p[i][i - j]; p[i][i - j] = tmp; } } for (; i < size; i += 2){ for (j = 0; j < (size - i)/2; j ++){ tmp = p[i][j]; p[i][j] = p[i][size - i - j - 1]; p[i][size - i - j - 1] = tmp; } } //按照斜线填入矩阵 for (i = 0; i <= n - 1; i ++){ for (j = 0; j <= i; j ++){ a[i - j][j] = p[i][j]; } } for (i = n ; i < size; i ++){ for (j = 0; j < (size - i); j ++){ a[n - j - 1][i - n + 1 + j] = p[i][j]; } } for (i = 0; i < n; i ++){ for (j = 0; j < n; j ++) cout << a[j][i] << ' '; cout << endl; } for (i = 0; i < size; i ++){ delete []p[i]; p[i] = NULL; } delete []p; p = NULL; for (i = 0; i < n; i ++){ delete []a[i]; a[i] = NULL; } delete []a; a = NULL; return 0; }
相关文章推荐
- switch语句的用法
- C++动态数组简单的模拟二元堆
- C++按位运算符
- c++web方案
- C语言:一组数据中只有一个数字出现了一次。其他所有数字都是成对出现的。请找出这个数字。(
- 【C语言】【笔试题】找出一组数据中成单出现的数字,其他所有数字都是成对出现的。(移位)
- 【C语言】不使用(a+b)/2这种方式,求两个数的平均值。
- 【C语言】【笔试题】编写函数: unsigned int reverse_bit(unsigned int value); 翻转二进制序列
- 【C语言】【笔试题】两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同
- 对于sizeof的含义、应用及易混点的解析
- VC++ 将资源位图画到窗口上去的方法
- C++函数指针简介
- C++函数指针简介
- C语言:不使用(a+b)/2这种方式(会溢出),求两个数的平均值
- C语言:编写函数将一个整数的二进制位模式从左到右翻转后的值输出
- C语言:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同(模除、移位)
- c语言 常量
- C++ 栈
- 总结sublime c++编译环境搭建 | 中文乱码问题解决方案 |sidebar配置 |sublime最佳插件列表|最佳主题方案
- C++ STL 排序(Sort)