题目 1465: [蓝桥杯][基础练习VIP]回形取数
时间限制: 1Sec 内存限制: 128MB
题目描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。
输入
输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。
输出
输出只有一行,共mn个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。
样例输入
3 3
1 2 3
4 5 6
7 8 9
样例输出
1 4 7 8 9 6 3 2 5
个人做题心得:
这是一道看似很简单,实则还行,操作下饭,debug难受的题目。
题目解析:
这道题目和之前记录的兰顿蚂蚁有些许相似之处,这样的一个回形取数就像蛇形取数一样。
讲讲自己的思路:
做题的几个点:
接下来是源代码(有不懂的可以留言):
#include
using namespace std;
int m,n;
int a[205][205];
int visit[205][205]={0};//访问数组
int num;
int x=0,y=0;
char s='D';
void turn1()// 向左转
{
switch(s)
{
case 'U': s='L'; break;
case 'R': s='U'; break;
case 'D': s='R'; break;
case 'L': s='D'; break;
}
}
void go()//朝着当前头朝向前行1
{
switch(s)
{
case 'U': x--; break;
case 'R': y++; break;
case 'D': x++; break;
case 'L': y--; break;
}
}
void back()//回退函数,用于返回上一个点,这里要注意xy的变化是根据转向前的情况来的
{
switch(s)
{
case 'U': y--; break;
case 'R': x--; break;
case 'D': y++; break;
case 'L': x++; break;
}
}
void circle()
{
while(num--)
{
if(x<m&&x>-1&&y<n&&y>-1&&visit[x][y]==0)//如果不越界且未被访问
{
cout<<a[x][y]<<" ";//取数
visit[x][y]=1;//标记已访问
if(num==0)break;//步数
}
go();
if(visit[x][y]!=0)//如果已经标记就转向
{
turn1();//转向
back();//回退
num++;//因为回退后的尝试情况也耗费步数,所以为了正常取数,耗费的步数要加上
}
else if((x>m-1||x<0)||(y>n-1||y<0))//越界就转向
{
turn1();
back();
num++;
continue;
}
else continue;
}
}
int main()
{
cin>>m>>n;
num=m*n;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
cin>>a[i][j];
}
}
circle();
}
这题目debug弄了好久,思想不难。
建议:
先把思路弄透彻了再考虑改代码,不然一会一个主意一会儿一个主意的改代码,真的极费时间。