废话不多说,上题目:
大意是:给一个m*n的矩阵,要你顺时针螺旋打印出里面的值。eg:
A
=
[
1
2
3
4
5
6
7
8
9
10
11
12
]
A= \left[ \begin{array}{ccc} 1 & 2 & 3 & 4\\ 5 & 6 & 7& 8\\ 9 & 10 & 11 & 12 \end{array} \right ]
A=⎣⎡159261037114812⎦⎤
输出:1 2 3 4 8 12 11 10 9 5 6 7
思考:
虽然说判定边界来控制循环绝对可以做,对不起,我在机试的时候脑子宕机了,而且最反感的就是判定这种找规律的边界条件的题,于是。。。我就对着这个题发呆了好久,,,自然就凉了。主要原因当然不是这个,嗯,是我太菜了,其实我想的是用回溯写。。。但是有点慌,就没写好歇菜了。
废话结束,回来查了一下网上相关题解。。。目前来说,我看到的全是找边界值,这很令人火大(也可能是我搜素技术不好,没看到)。然后我仔细考虑了一下,终于把回溯版的写好了,代码如下:(是不是感觉看起来舒服多了.jpg)
#include <iostream>
#include <string.h>
using namespace std;
bool A[100][100]; //表明该值未被输出过,True代表未走过,False反之
int C[100][100]; //要存的值
int row,col; //输入矩阵行数、列数
void fun(int x,int y,bool flag=true){
/*
(x,y):所在位置坐标
flag:是否是从下往上走
flag=true代表非从下往上走(一般情况,不用特判),
反之要改成先判定上面的块是否能走,再判定右侧的块是否能走
*/
if(x>=row||x<0||y>=col||y<0) return ;
if(A[x][y]==false) return ;
cout<<C[x][y]<<" ";
A[x][y]=false;
if(flag){
fun(x,y+1);
fun(x+1,y);
fun(x,y-1);
fun(x-1,y,false);
}
else{
fun(x-1,y,false);
fun(x,y+1);
}
}
int main()
{
cin>>row>>col;
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
cin>>C[i][j];
memset(A,true,sizeof(A));
fun(0,0);
return 0;
}
菜鸡还在恶补初步中,若有bug请各位赐教。
需要注意的点:
一开始是没有特判的,这就导致不是顺时针螺旋输出,成了“s”型输出值。对于上面那个矩阵A当然不会出错,但是如果是这种:
B
=
[
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
]
B= \left[ \begin{array}{ccc} 1 & 2 & 3 & 4\\ 5 & 6 & 7& 8\\ 9 & 10 & 11 & 12\\ 13 & 14 & 15 & 16 \end{array} \right ]
B=⎣⎢⎢⎡15913261014371115481216⎦⎥⎥⎤
在fun函数中不写else那一段的话,输出就变成了:
1 2 3 4 8 12 16 15 14 13 9 10 11 7 6 5
这主要是因为:
对于从下往上2走的话,按照一般的规律,是先看右侧能不能走,这就会在9处产生错误。当然,只有这种情况才会出现问题,因为对于从左往右走、从上往下和从右往左都会按照那个顺序跑的,所以不用担心。