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

问题描述
  回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转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

思路:回形取数的顺序是向下、右、上、左的循环,而每次走到尽头需要判断然后改正方向,所以我采取了多建立一圈数组的形式,就是在原本存放数组的周围围上一层值为-1的元素,让每次取数时,碰到-1就转换方向,从而实现回形取数,详情见代码里的注释。

代码:

public class test {
	public static void main(String[] args) {
                Scanner input = new Scanner(System.in);
		int m = input.nextInt();//行
		int n = input.nextInt();//列
		
		//为了标记,我吧本来的n×m数组周围再加上一圈,赋值为-1
		final int x = m + 2;//数组的行
		final int y = n + 2;//数组的列
		int[][] mn = new int[x][y];
		
		//初始化数组,mn[1][1]到mn[m][n]的范围内存放本身的数组
		for(int i = 0 ; i < x ; i++ ) {
			for(int j = 0 ; j < y ; j++	) {
				if( i == 0 || i == x - 1 ) {
					mn[i][j] = -1;
				}
				else {
					if(j == 0 || j == y - 1)
						mn[i][j] = -1;
					else {
						mn[i][j] = input.nextInt();
					}
				}
			}
		}
		
		int a = 1 ;
		int b = 1 ;
		int count = 1;//初始化记号器
		
		while(true) {
			//count=1时表示向下取数,2表示向右,3向上,4向左
			//取完往对应方向移动一个,并且把已经打印的赋值为-1
			//如果一列取到尽头了,处理一下count,让count变换方向
			if(count % 4 == 1) {
				
				//打印
				while(mn[a][b] != -1) {
					System.out.print(mn[a][b] + " ");
					mn[a][b] = -1;
					a++;
				}
				//遇到-1的时候,已经移动到边界的-1上,需要--a和b的坐标来处理count
				//因为往下取完后,是往右取,所以处理完count需要将b++,跳到右边元素
				if(mn[a][b] == -1) {
					count = dealCount(mn ,--a ,b++ );
					continue;
				}
				
			}
			
			if(count % 4 == 2) {
				
				while(mn[a][b] != -1) {
					System.out.print(mn[a][b] + " ");
					mn[a][b] = -1;
					b++;
				}
				if(mn[a][b] == -1) {
					count = dealCount(mn ,a-- ,--b );//跳到上面的元素
					continue;
				}
				
			}
			
			if(count % 4 == 3) {
				
				while(mn[a][b] != -1) {
					System.out.print(mn[a][b] + " ");
					mn[a][b] = -1;
					a--;
				}
				if(mn[a][b] == -1) {
					count = dealCount(mn ,++a ,b-- );//跳到左边的元素
					continue;
				}
				
			}
			
			if(count % 4 == 0) {
				
				while(mn[a][b] != -1) {
					System.out.print(mn[a][b] + " ");
					mn[a][b] = -1;
					b--;
				}
				if(mn[a][b] == -1) {
					count = dealCount(mn ,a++ ,++b );//跳到下面的元素
					continue;
				}
				
			}
			if(count == -2)break;//count返回-2则取完了跳出循环
		}	
	}
	public static int dealCount(int[][] arr,int x ,int y) {
		int count = -2;
		//如果周围没有不是-1的数了,证明全取完了,返回-2加以辨识
		if(arr[x + 1][y] != -1)
			count = 1;
		if(arr[x][y + 1] != -1)
			count = 2;
		if(arr[x - 1][y] != -1)
			count = 3;
		if(arr[x][y - 1] != -1)
			count = 0;
		return count;
		
	}
}

猜你喜欢

转载自blog.csdn.net/likunkun__/article/details/79721434