题目描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转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
思路:
思路很简单,就是按照逆时针方向(下-右-上-左)不断遍历,直到某一个方向走到边界或者已被访问过后改变方向;
初代码 (这个代码没AC,可以直接跳过看后面)
这个代码不知道为什么没过,自己也没检查出什么错误。
(以后有时间再看看,有人看出来也可以评论告知一下)
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
int map[210][210]; //地图
int m,n;
bool vis[210][210]={false}; //记录是否访问过
vector<int> ans; //记录答案
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1}; /*按照取数的方向 下-右-上-左 这个顺序
一直循环取数,每个方向都是
取到不能取(即边界或者已取过),再改变方向*/
int cnt=0;
void dfs(int x,int y,int direction) /*用来表示当前方向,下-右-上-左
分别用0123表示 */
{
if(cnt==n*m)
return;
vis[x][y]=1;
cnt++;
ans.push_back(map[x][y]); //记录答案
if(direction==0) //不断向下访问,直接访问不了,改变方向
{
while(1)
{
int newx=x+dx[0];
int newy=y+dy[0];
if(vis[newx][newy]==false && map[newx][newy])
dfs(newx,newy,0);
else break;
}
direction = 1;
}
if(direction==1) //不断向右访问,直接访问不了,改变方向
{
while(1)
{
int newx=x+dx[1];
int newy=y+dy[1];
if(vis[newx][newy]==false && map[newx][newy])
dfs(newx,newy,1);
else break;
}
direction = 2;
}
if(direction==2) //不断向上访问,直接访问不了,改变方向
{
while(1)
{
int newx=x+dx[2];
int newy=y+dy[2];
if(vis[newx][newy]==false && map[newx][newy])
dfs(newx,newy,2);
else break;
}
direction = 3;
}
if(direction==3) // //不断向左访问,直接访问不了,改变方向
{
while(1)
{
int newx=x+dx[3];
int newy=y+dy[3];
if(vis[newx][newy]==false && map[newx][newy])
dfs(newx,newy,3);
else break;
}
direction = 0;
}
}
int main()
{
cin>>m>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
cin>>map[i][j];
dfs(1,1,0);
for(int i=0;i<ans.size();i++) //输出答案
{
cout<<ans[i];
if(i<ans.size()-1)
cout<<" ";
}
return 0;
}
几种不同情况都是对的,代码明明就很ok嘛。。。
AC代码:
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
int map[210][210]; //地图
int m,n;
bool vis[210][210]={false}; //记录是否访问过
vector<int> ans; //记录答案
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1}; /*按照取数的方向 下-右-上-左 这个顺序一直循环取数
每个方向都是取到不能取(即边界或者已取过),再改变方向*/
void dfs(int x,int y,int direction)//用来表示当前方向,下-右-上-左分别用0123表示
{
vis[x][y]=1; //标记访问过
int newx=x+dx[direction]; //下一个点
int newy=y+dy[direction];
if(vis[newx][newy]==1 || newx<1 || newx>m || newy<1 || newy>n)
//访问过 或者 出边界(即到不了这个点)
{
if(ans.size()==n*m) return; //如果取出的值等于n*m个,代表取完
direction=(direction+1)%4; //改变方向
dfs(x,y,direction); //重新走这个点
}
else //可以到达这个点
{
ans.push_back(map[newx][newy]); //加入数组
dfs(newx,newy,direction); //继续遍历下一个点
}
}
int main()
{
cin>>m>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++) //存图
cin>>map[i][j];
ans.push_back(map[1][1]); //放入第一个点
dfs(1,1,0);
for(int i=0;i<ans.size();i++) //输出答案
{
cout<<ans[i];
if(i<ans.size()-1)
cout<<" ";
}
return 0;
}