C++蓝桥杯 基础练习之回形取数

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;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值