C++ 蓝桥杯题目讲解汇总(持续更新)
VIP试题 回形取数
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转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
样例输入
3 2
1 2
3 4
5 6
样例输出
1 3 5 6 4 2
思路
首先要搞清楚方向 下 右 上 左 移动的时候要判读状态是否需要移动
代码
方案一:
判断下一个状态是否需要移动,需要注意索引不能越界
#include<iostream>
#include<string.h>
#define N 205
using namespace std;
int main(){
int n,m;
cin>>n>>m;
int res[N][N];
int a[N][N];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>a[i][j];
memset(res,1,sizeof(res));
//方法,首先第一个为0,代表走过的,判断下一次要走的方向的格子是否为1,
//如果为1,就将下一个格子置为1,对于蛇形来说+1 -1 代表着方向,但是只改变当前的状态,
//就会导致存在某一个点最后永远无法到达,因为到了那个点,但是他的下一个位置却是走过的
int i=0,j=0,ct=0;
res[0][0]=0;
cout<<a[0][0]<<" ";
while(ct<n*m-1){
while(i<n-1&&res[i+1][j]!=0) {
i++;
cout<<a[i][j]<<" ";
res[i][j]=0;
ct++;
}
while(j<m-1&&res[i][j+1]!=0){
j++;
cout<<a[i][j]<<" ";
res[i][j]=0;
ct++;
}
while(i>-1&&res[i-1][j]!=0&&i-1>=0) {
i--;
cout<<a[i][j]<<" ";
res[i][j]=0;
ct++;
}
while(j>-1&&res[i][j-1]!=0&&j-1>=0){
j--;
res[i][j]=0;
cout<<a[i][j]<<" ";
ct++;
}
}
return 0;
}
方案二
判断当前的位置的状态,进而判断是否需要移动,还是下右上左,需要注意是否会多走
#include<iostream>
#include<string.h>
#define N 205
using namespace std;
// 下 右 上 左
int main(){
int n,m;
cin>>n>>m;
int a[N][N];
int res[N][N];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>a[i][j];
// int js=0;
// cout<<js++<<endl;
// js=0;
// cout<<++js<<endl;
memset(res,0,sizeof res);
int i=0,j=0,ct=0;
//从0 0开始移动
while(ct<n*m){
while(i<n&&res[i][j]==0) {
cout<<a[i][j]<<" ";
res[i][j]=1;
i++;
ct++;
}
i--;
j++;
//移动到最下方的时候,i会多移动一下,所以--,除以以外还要手动控制j++,使得向右移动
while(j<m&&res[i][j]==0){
cout<<a[i][j]<<" ";
res[i][j]=1;
j++;
ct++;
}
i--;
j--;
while(i>-1&&!res[i][j]) {
cout<<a[i][j]<<" ";
res[i][j]=1;
i--;
ct++;
// cout<<"###"<<i<<" "<<res[i-1][j]<<endl;
}
i++;
j--;
while(j>-1&&!res[i][j]){
cout<<a[i][j]<<" ";
res[i][j]=1;
j--;
ct++;
}
i++;
j++;
// cout<<i<<" "<<j<<" "<<endl;
}
return 0;
}