您的位置:首页 > 编程语言 > C语言/C++

C/C++面试(3)——矩阵编程题(模拟法)

2015-10-24 14:31 696 查看
谈谈机试吧,虽然一举通过某知名学府的机试获得预录取,但是之后找实习过程中的机试通过率只有10%,十分惭愧。所以特地开了编程版,之后继续有彩蛋(⊙o⊙)哦~

链接里面有很多种方法,在这里,我只提出一种方法,只要稍加改动,就可以解决螺旋矩阵和回字矩阵了,具有一定的通用性吧。

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: