蓝桥杯 -- 回行取数

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

 

posted on 2017-12-27 18:00  c_night  阅读(554)  评论(0编辑  收藏  举报