蓝桥杯 基础练习 回形取数

这里写图片描述

*递归的层数太多,不能符合蓝桥杯的要求,故使用循环。


import java.util.Scanner;

public class Main{

    /**
     * 判断该方向上是否可以取数
     * @param m 数组行数
     * @param n 数组列数
     * @param dire 取数方向
     * @param x 取数当前行数
     * @param y 取数当前列数
     * @param flags 取数标记
     * @return true表示该方向上可以取数,false则反之
     */
    public static boolean judge(int m,int n,int dire,int x,int y,boolean[][] flags){
        switch(dire) {
        case 0:return m > x + 1 && !flags[x + 1][y];
        case 1:return n > y + 1 && !flags[x][y + 1];
        case 2:return x - 1 >= 0 && !flags[x - 1][y];
        case 3:return y - 1 >= 0 && !flags[x][y - 1];
        default:return false;
        }
    }

    /**
     * 非递归回行取数
     * @param arr 输入的数据
     */
    public static void huixingqushu(int[][] arr)
    {
        //初始化
        int m = arr.length;
        int n = arr[0].length;
        boolean[][] flags = new boolean[m][n];
        int dire = 0;
        int x,y;
        x = y = 0;

        System.out.print(arr[x][y]);//先取出第一个数
        flags[x][y] = true;
        boolean resflag = true;
        while(resflag) {
            switch(dire) {
            case 0:{
                if(judge(m,n,0,x,y,flags)) {
                    //若往下可以取数,则继续往下取
                    System.out.print(" "+arr[++x][y]);
                    flags[x][y] = true;
                }
                else if(judge(m,n,1,x,y,flags)) {
                    //若往右可以取数,则改变方向往右取
                    System.out.print(" "+arr[x][++y]);
                    flags[x][y] = true;
                    dire = (dire + 1) % 4;
                }
                else resflag = false;//下方和右方都不可取数,取数完成
                break;
            }
            case 1:{
                if(judge(m,n,1,x,y,flags)) {
                    //若往右可以取数,则继续往右取
                    System.out.print(" "+arr[x][++y]);
                    flags[x][y] = true;
                }
                else if(judge(m,n,2,x,y,flags)) {
                    //若往上可以取数,则改变方向往上取
                    System.out.print(" "+arr[--x][y]);
                    flags[x][y] = true;
                    dire = (dire + 1) % 4;
                }
                else resflag = false;//右方和上方都不可取数,取数完成
                break;
            }
            case 2:{
                if(judge(m,n,2,x,y,flags)) {
                    //若往上可以取数,则继续往上取
                    System.out.print(" "+arr[--x][y]);
                    flags[x][y] = true;
                }
                else if(judge(m,n,3,x,y,flags)) {
                    //若往左可以取数,则改变方向往左取
                    System.out.print(" "+arr[x][--y]);
                    flags[x][y] = true;
                    dire = (dire + 1) % 4;
                }
                else resflag = false;//上方和左方都不可取数,取数完成
                break;
            }
            case 3:{
                if(judge(m,n,3,x,y,flags)) {
                    //若往左可以取数,则继续往左取
                    System.out.print(" "+arr[x][--y]);
                    flags[x][y] = true;
                }
                else if(judge(m,n,0,x,y,flags)) {
                    //若往下可以取数,则改变方向往下取
                    System.out.print(" "+arr[++x][y]);
                    flags[x][y] = true;
                    dire = (dire + 1) % 4;
                }
                else resflag = false;//左方和下方都不可取数,取数完成
                break;
            }
        }
        }
    }

    /**
     * 递归回行取数
     * @param arr 输入的数据
     * @param dest 取数方向   0:down  1:right   2:up   3: left
     * @param x 取数当前行数
     * @param y 取数当前列数
     * @param flags 取数标记
     */
    public static void huixingqushu(int[][] arr,int dire,int x,int y,boolean[][] flags){
        int res = arr[x][y];
        System.out.print(" "+res);
        System.out.flush();
        flags[x][y] = true;
        int m = arr.length;
        int n = arr[0].length;
        switch(dire) {
            case 0:{
                if(judge(m,n,0,x,y,flags)) 
                    //若往下可以取数,则继续往下取
                    huixingqushu(arr,dire,x + 1,y,flags);
                else if(judge(m,n,1,x,y,flags))
                    //若往右可以取数,则改变方向往右取
                    huixingqushu(arr,(dire + 1) % 4,x,y + 1,flags);
                else return;//下方和右方都不可取数,取数完成
            }
            case 1:{
                if(judge(m,n,1,x,y,flags)) 
                    //若往右可以取数,则继续往右取
                    huixingqushu(arr,dire,x,y + 1,flags);
                else if(judge(m,n,2,x,y,flags))
                    //若往上可以取数,则改变方向往上取
                    huixingqushu(arr,(dire + 1) % 4,x - 1,y,flags);
                else return;//右方和上方都不可取数,取数完成
            }
            case 2:{
                if(judge(m,n,2,x,y,flags)) 
                    //若往上可以取数,则继续往上取
                    huixingqushu(arr,dire,x - 1,y,flags);
                else if(judge(m,n,3,x,y,flags))
                    //若往左可以取数,则改变方向往左取
                    huixingqushu(arr,(dire + 1) % 4,x,y - 1,flags);
                else return;//上方和左方都不可取数,取数完成
            }
            case 3:{
                if(judge(m,n,3,x,y,flags)) 
                    //若往左可以取数,则继续往左取
                    huixingqushu(arr,dire,x,y - 1,flags);
                else if(judge(m,n,0,x,y,flags))
                    //若往下可以取数,则改变方向往下取
                    huixingqushu(arr,(dire + 1) % 4,x + 1,y,flags);
                else return;//左方和下方都不可取数,取数完成
            }
        }
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int m = scan.nextInt();
        int n = scan.nextInt();
        int[][] arr = new int[m][n];
        for(int i = 0; i < m; i++)
        for(int j = 0; j < n; j++)
            arr[i][j] = scan.nextInt();
        scan.close();

        /***************递归回行取数程序段 **************/
//      System.out.print(arr[0][0]);//先取出第一个数
//      boolean[][] flags = new boolean[m][n];
//      flags[0][0] = true;
//      if(m <= 1 && n <= 1) {}//若最多只有一个数,则取数完成,不做任何操作
//      else if(m <= 1)
//          //若往下不可取数,则往右取
//          huixingqushu(arr,1,0,1,flags);
//      else
//          //否则往下取
//          huixingqushu(arr,0,1,0,flags);
        /*****************NED*********************/

        /***************非递归回行取数程序段 **************/
        huixingqushu(arr);
        /*****************NED*********************/
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值