蓝桥杯 -- 回行取数
问题描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。
输入格式
输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。
输出格式
输出只有一行,共mn个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。
样例输入
3 3
1 2 3
4 5 6
7 8 9
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 2
3 4
5 6
样例输出
1 3 5 6 4 2
使用递归和非递归实现
非递归算法完美通过了,递归算法 某些数据堆栈溢出
1 import java.util.Scanner; 2 3 public class Main{ 4 5 /** 6 * 判断该方向上是否可以取数 7 * @param m 数组行数 8 * @param n 数组列数 9 * @param dire 取数方向 10 * @param x 取数当前行数 11 * @param y 取数当前列数 12 * @param flags 取数标记 13 * @return true表示该方向上可以取数,false则反之 14 */ 15 public static boolean judge(int m,int n,int dire,int x,int y,boolean[][] flags){ 16 switch(dire) { 17 case 0:return m > x + 1 && !flags[x + 1][y]; 18 case 1:return n > y + 1 && !flags[x][y + 1]; 19 case 2:return x - 1 >= 0 && !flags[x - 1][y]; 20 case 3:return y - 1 >= 0 && !flags[x][y - 1]; 21 default:return false; 22 } 23 } 24 25 /** 26 * 非递归回行取数 27 * @param arr 输入的数据 28 */ 29 public static void huixingqushu(int[][] arr) 30 { 31 //初始化 32 int m = arr.length; 33 int n = arr[0].length; 34 boolean[][] flags = new boolean[m][n]; 35 int dire = 0; 36 int x,y; 37 x = y = 0; 38 39 System.out.print(arr[x][y]);//先取出第一个数 40 flags[x][y] = true; 41 boolean resflag = true; 42 while(resflag) { 43 switch(dire) { 44 case 0:{ 45 if(judge(m,n,0,x,y,flags)) { 46 //若往下可以取数,则继续往下取 47 System.out.print(" "+arr[++x][y]); 48 flags[x][y] = true; 49 } 50 else if(judge(m,n,1,x,y,flags)) { 51 //若往右可以取数,则改变方向往右取 52 System.out.print(" "+arr[x][++y]); 53 flags[x][y] = true; 54 dire = (dire + 1) % 4; 55 } 56 else resflag = false;//下方和右方都不可取数,取数完成 57 break; 58 } 59 case 1:{ 60 if(judge(m,n,1,x,y,flags)) { 61 //若往右可以取数,则继续往右取 62 System.out.print(" "+arr[x][++y]); 63 flags[x][y] = true; 64 } 65 else if(judge(m,n,2,x,y,flags)) { 66 //若往上可以取数,则改变方向往上取 67 System.out.print(" "+arr[--x][y]); 68 flags[x][y] = true; 69 dire = (dire + 1) % 4; 70 } 71 else resflag = false;//右方和上方都不可取数,取数完成 72 break; 73 } 74 case 2:{ 75 if(judge(m,n,2,x,y,flags)) { 76 //若往上可以取数,则继续往上取 77 System.out.print(" "+arr[--x][y]); 78 flags[x][y] = true; 79 } 80 else if(judge(m,n,3,x,y,flags)) { 81 //若往左可以取数,则改变方向往左取 82 System.out.print(" "+arr[x][--y]); 83 flags[x][y] = true; 84 dire = (dire + 1) % 4; 85 } 86 else resflag = false;//上方和左方都不可取数,取数完成 87 break; 88 } 89 case 3:{ 90 if(judge(m,n,3,x,y,flags)) { 91 //若往左可以取数,则继续往左取 92 System.out.print(" "+arr[x][--y]); 93 flags[x][y] = true; 94 } 95 else if(judge(m,n,0,x,y,flags)) { 96 //若往下可以取数,则改变方向往下取 97 System.out.print(" "+arr[++x][y]); 98 flags[x][y] = true; 99 dire = (dire + 1) % 4; 100 } 101 else resflag = false;//左方和下方都不可取数,取数完成 102 break; 103 } 104 } 105 } 106 } 107 108 /** 109 * 递归回行取数 110 * @param arr 输入的数据 111 * @param dest 取数方向 0:down 1:right 2:up 3: left 112 * @param x 取数当前行数 113 * @param y 取数当前列数 114 * @param flags 取数标记 115 */ 116 public static void huixingqushu(int[][] arr,int dire,int x,int y,boolean[][] flags){ 117 int res = arr[x][y]; 118 System.out.print(" "+res); 119 System.out.flush(); 120 flags[x][y] = true; 121 int m = arr.length; 122 int n = arr[0].length; 123 switch(dire) { 124 case 0:{ 125 if(judge(m,n,0,x,y,flags)) 126 //若往下可以取数,则继续往下取 127 huixingqushu(arr,dire,x + 1,y,flags); 128 else if(judge(m,n,1,x,y,flags)) 129 //若往右可以取数,则改变方向往右取 130 huixingqushu(arr,(dire + 1) % 4,x,y + 1,flags); 131 else return;//下方和右方都不可取数,取数完成 132 } 133 case 1:{ 134 if(judge(m,n,1,x,y,flags)) 135 //若往右可以取数,则继续往右取 136 huixingqushu(arr,dire,x,y + 1,flags); 137 else if(judge(m,n,2,x,y,flags)) 138 //若往上可以取数,则改变方向往上取 139 huixingqushu(arr,(dire + 1) % 4,x - 1,y,flags); 140 else return;//右方和上方都不可取数,取数完成 141 } 142 case 2:{ 143 if(judge(m,n,2,x,y,flags)) 144 //若往上可以取数,则继续往上取 145 huixingqushu(arr,dire,x - 1,y,flags); 146 else if(judge(m,n,3,x,y,flags)) 147 //若往左可以取数,则改变方向往左取 148 huixingqushu(arr,(dire + 1) % 4,x,y - 1,flags); 149 else return;//上方和左方都不可取数,取数完成 150 } 151 case 3:{ 152 if(judge(m,n,3,x,y,flags)) 153 //若往左可以取数,则继续往左取 154 huixingqushu(arr,dire,x,y - 1,flags); 155 else if(judge(m,n,0,x,y,flags)) 156 //若往下可以取数,则改变方向往下取 157 huixingqushu(arr,(dire + 1) % 4,x + 1,y,flags); 158 else return;//左方和下方都不可取数,取数完成 159 } 160 } 161 } 162 public static void main(String[] args) { 163 Scanner scan = new Scanner(System.in); 164 int m = scan.nextInt(); 165 int n = scan.nextInt(); 166 int[][] arr = new int[m][n]; 167 for(int i = 0; i < m; i++) 168 for(int j = 0; j < n; j++) 169 arr[i][j] = scan.nextInt(); 170 scan.close(); 171 172 /***************递归回行取数程序段 **************/ 173 // System.out.print(arr[0][0]);//先取出第一个数 174 // boolean[][] flags = new boolean[m][n]; 175 // flags[0][0] = true; 176 // if(m <= 1 && n <= 1) {}//若最多只有一个数,则取数完成,不做任何操作 177 // else if(m <= 1) 178 // //若往下不可取数,则往右取 179 // huixingqushu(arr,1,0,1,flags); 180 // else 181 // //否则往下取 182 // huixingqushu(arr,0,1,0,flags); 183 /*****************NED*********************/ 184 185 /***************非递归回行取数程序段 **************/ 186 huixingqushu(arr); 187 /*****************NED*********************/ 188 } 189 }