【题目】
问题描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转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
【分析】
由于运动有四个方向,我们只有确定当前所处的方向的时候才能知道下一步往哪里走
ULDR 表示上右下左四个方向,它代表了左转的次序,-1表示这个位置已经取过。
【源码】
private static String s = "ULDR";
public static void main(String[] args) {
//*****从控制台读取并存储数据*****
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] a = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = sc.nextInt();
}
}
sc.close();
//************************
walk(a,m, n, 0, 0, 'D', 0);
}
//递归取数函数
private static void walk(int[][] a, int m, int n, int i, int j, char d, int step) {
printN(a, i, j);
//递归出口
if(step == m*n) {
return;
}
//确定方向
while (true) {
switch (d) {
case 'U':
if(i-1<0 || a[i-1][j]==-1) {
d = getNext(d);
continue;
}
break;
case 'L':
if(j-1<0 || a[i][j-1]==-1) {
d = getNext(d);
continue;
}
break;
case 'D':
if(i+1>=m || a[i+1][j]==-1) {
d = getNext(d);
continue;
}
break;
case 'R':
if(j+1>=n || a[i][j+1] == -1) {
d=getNext(d);
continue;
}
break;
}
break;
}
//去取下一个数
switch (d) {
case 'U':
walk(a, m, n, i-1, j, d, step+1);
break;
case 'L':
walk(a, m, n, i, j-1, d, step+1);
break;
case 'D':
walk(a, m, n, i+1, j, d, step+1);
break;
case 'R':
walk(a, m, n, i, j+1, d, step+1);
break;
}
}
private static void printN(int[][] a, int i ,int j) {
System.out.print(" " + a[i][j]);
a[i][j] = -1;
}
//调整方向函数,左转90度
private static char getNext(char d) {
int index = s.indexOf(d);
index++;
if(index == s.length()) {
index = 0;
}
return s.charAt(index);
}