蓝桥杯基础练习-回形取数

蓝桥杯 基础练习 回形取数

问题描述
  回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。
输入格式
  输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。
输出格式
  输出只有一行,共m*n个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。
样例输入:
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
我的解决思路:
先观察每一圈输出数据的规律:
第一次:从二维数组的起点(0,0)开始,遍历一圈,记为第一圈的数据;
第二次(如果有):从(0+1,0+1)开始 (这是因为(1,0),(0,1)一定会被第一圈取出,并且如果有第二圈,必然从(0+1,0+1)开始),那么和第一圈一样的,遍历一圈,记为第二圈的数据;
第三次(如果有):从(1+1,1+1)开始,后面依次类推;
那么,什么时候到终止呢?我的结论是当矩形圈的某一个长度小于等于0的时候
看上面第一个输入例子:第一圈是将外面一层14789632输出,那么第二圈矩形圈向下(上)的长度为:3-2=1;矩形圈向右(左)的长度为:3-2=1;都大于0,可以进行第二圈;
第二圈是将5输出,那么第三圈矩形圈向下(上)的长度为:1-2=-1;矩形圈向右(左)的长度为:1-2=-1;都小于0,那么不可以进行第三圈;此时程序就结束了,完成了题目要求的输出。
根据上述的思路我们可以得到如下的编程:
首先将数据存放在二维数组中,使用递归的思想进行第一圈的遍历输出(输入第一圈的起始点,第一圈的向下(上)的长度,第一圈的向右(左)的长度),接着第二圈,第三圈…在每一圈开始的时候需要判断是否可以开始下一圈,判断条件为矩形圈向下(上)的长度和矩形圈向右(左)的长度即:rowLen>0&&columnLen>0即可。
代码如下(JAVA)

import java.util.Scanner;

public class Main {
	
	static int[][] arr = null;//存放输入数据
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int row = scanner.nextInt();
		int column = scanner.nextInt();
		arr = new int[row][column];
		for(int i = 0;i<row;i++) {
			for(int j = 0;j<column;j++) {
				arr[i][j] = scanner.nextInt();
			}
		}
		//进行第一圈遍历
		getResult(0,0,row,column);
	}

	private static void getResult(int n, int m,int rowLen,int columnLen) {
		// 对每一个起点为(n,m)的圈进行输出,并将圈缩小,因为下一个圈是在起点的对角线开始
		//例如(0,0)完了肯定是从(1,1)开始
		if(rowLen>0 && columnLen>0) {  //判断是否可以开始这一圈的遍历输出
			//输出这一圈的数据
			printArr(n,m,rowLen,columnLen);
			//进行下一圈
			getResult(n+1,m+1,rowLen-2,columnLen-2);
		}
	}

	private static void printArr(int n, int m, int rowLen, int columnLen) {
		// 将起点为(n,m)的圈进行打印,注意不要弄错坐标
		if(rowLen == 1 && columnLen==1) {
			System.out.print(arr[n][m]+" ");
		}else if (rowLen == 1) {
			for(int i = m;i<m+columnLen;i++) {
				System.out.print(arr[n][i]+" ");
			}
		}else if (columnLen == 1) {
			for(int i = n;i<n+rowLen;i++) {
				System.out.print(arr[i][m]+" ");
			}
		}else {
			for(int i = n;i<n+rowLen;i++) {
				System.out.print(arr[i][m]+" ");
			}
			for(int i = m+1;i<m+columnLen;i++) {
				System.out.print(arr[n+rowLen-1][i]+" ");
			}
			for(int i = n+rowLen-2;i>=n;i--) {
				System.out.print(arr[i][m+columnLen-1]+" ");
			}
			for(int i = m+columnLen-2;i>m;i--) {
				System.out.print(arr[n][i]+" ");
			}
		}
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值