模擬立方體的滾動(dòng)并記錄路徑

立方體滾動(dòng)

一個(gè)立方體每個(gè)面都有一種顏色,顏色分別用 1,2,3,4,5,6 表示,立方體在一塊 n*n 的方格棋盤上滾動(dòng),棋盤上的格子會(huì)被立方體的底面染色,給出棋盤的維度大小及立方體在棋盤上的滾動(dòng)路徑,輸出路徑上格子的顏色。

立方體初始狀態(tài)及下面示例的輸入對應(yīng)路徑如下圖:

cube-roll.png

輸入:

5
S # # # .
. . . # .
E # . # #
. # . . #
. # # # #

說明:

第一行輸入一個(gè)整數(shù) n ,代表棋盤的維度是 n*n

之后有 n 行輸入,表示棋盤上的占位符,各符號有如下含義:

  • S ,表示起點(diǎn)
  • # ,表示立方體經(jīng)過該格子
  • . ,表示棋盤上其他的格子(不在立方體路徑上)

注意:由于只用字符表示路徑上的位置,并不知道滾動(dòng)位置的先后順序,故必須對輸入有要求:只能夠由輸入推斷得到一條路徑,不能產(chǎn)生歧義,否則視為不合法的輸入

代碼:


import java.util.Scanner;

class Cube {
    int up = 1;
    int down = 6;
    int left = 5;
    int right = 2;
    int front = 3;
    int back = 4;

    public void rollRight() { // 向右滾動(dòng)

        int t1 = 0, t2 = 0; // 臨時(shí)變量,用于保存被覆蓋的值

        t1 = down;
        down = right; // 底面由之前的右面替代
        t2 = left;
        left = t1; // 左面由之前的下面替代
        t1 = up;
        up = t2; // 上面由之前的左面替代
        right = t1; // 右面由之前的上面替代

        // 前面和后面都不會(huì)變

    }
    // 下面的滾動(dòng)與上面的操作是類似的,不再注釋

    public void rollLeft() {

        int t1 = 0, t2 = 0;

        t1 = down;
        down = left;
        t2 = right;
        right = t1;
        t1 = up;
        up = t2;
        left = t1;

    }

    public void rollUp() {

        int t1 = 0, t2 = 0;

        t1 = down;
        down = back;
        t2 = front;
        front = t1;
        t1 = up;
        up = t2;
        back = t1;

    }

    public void rollDown() {

        int t1 = 0, t2 = 0;

        t1 = down;
        down = front;
        t2 = back;
        back = t1;
        t1 = up;
        up = t2;
        front = t1;

    }

    // 用于測試,方便打印立方體
    @Override
    public String toString() {
        return "Cube [up=" + up + ", down=" + down + ", left=" + left + ", right=" + right + ", front=" + front
                + ", back=" + back + "]";
    }

}

class Position { // 棋盤上坐標(biāo)的抽象

    int x = 0;
    int y = 0;

    Position(int x, int y) {
        this.x = x;
        this.y = y;

    }

    // 用于測試,方便打印位置
    @Override
    public String toString() {
        return "Position [x=" + x + ", y=" + y + "]";
    }

}

class Board { // 棋盤抽象

    char[][] board; // 使用二維數(shù)組表示棋盤
    boolean[][] visited; // 用于表示棋盤上的位置是否被訪問過,visited[i][j]=true 表示坐標(biāo) (i,j) 被訪問過,否則沒訪問過
    // up:1
    // down:2
    // left:3
    // right:4
    short[][] nextDirection; // 棋盤上每個(gè)位置上的下一個(gè)滾動(dòng)的方向,nextDirection[i][j]=1 表示在 (i,j) 時(shí)下一個(gè)方向要向上滾動(dòng)
    int dimension = 0; // 棋盤的維度

    Board(int n) { // 初始化
        board = new char[n][n];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++) {

                board[i][j] = '.';

            }

        visited = new boolean[n][n];
        nextDirection = new short[n][n];
        dimension = n;
    }

    Position getStartPosition() { // 找出起始位置

        for (int i = 0; i < dimension; i++) {
            for (int j = 0; j < dimension; j++) {
                if (board[i][j] == 'S') {
                    visited[i][j] = true;
                    return new Position(i, j);
                }

            }
        }

        throw new RuntimeException("invalid rolling path : no start");
    }

    Position getNextPosition(Position pos) { // 在位置 pos 時(shí),其下一個(gè)滾動(dòng)到的位置

        int i = pos.x, j = pos.y;

        Position resPosition = null;

        // 檢查 pos 的右側(cè)是否是下一個(gè)位置
        if (j < board.length - 1 && board[i][j + 1] != '.' && visited[i][j + 1] == false) {
            nextDirection[i][j] = 4; // 當(dāng)前位置 pos 的下一個(gè)方向就是向右
            resPosition = new Position(i, j + 1);
        } else if (j > 0 && board[i][j - 1] != '.' && visited[i][j - 1] == false) {
            nextDirection[i][j] = 3;
            resPosition = new Position(i, j - 1);
        } else if (i < board.length - 1 && board[i + 1][j] != '.' && visited[i + 1][j] == false) {
            nextDirection[i][j] = 2;
            resPosition = new Position(i + 1, j);
        } else if (i > 0 && board[i - 1][j] != '.' && visited[i - 1][j] == false) {
            nextDirection[i][j] = 1;
            resPosition = new Position(i - 1, j);
        } else {
            throw new RuntimeException("invalid rolling path");
        }

        visited[i][j] = true; // 標(biāo)記當(dāng)前位置 pos 被訪問過

        return resPosition;

    }

    void printBoard() { // 打印棋盤
        for (int i = 0; i < dimension; i++) {
            for (int j = 0; j < dimension; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();

        }

    }

}

public class RollingCube {

    public static void main(String[] args) {

        Cube cube = new Cube();

        Board board;

        Scanner in = new Scanner(System.in);
        int n = in.nextInt(); // 棋盤維度從鍵盤輸入獲取

        board = new Board(n);

        // 將輸入的路徑記錄在棋盤中
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                board.board[i][j] = in.next().charAt(0);
            }

        }

        board.printBoard();

        Position pos = board.getStartPosition(); // 找到起始位置

        int x = pos.x, y = pos.y;

        while (board.board[x][y] != 'E') { // 只要沒到終點(diǎn),一直滾動(dòng)

            board.board[x][y] = String.valueOf(cube.down).charAt(0); // 將立方體的下面(底面)的值記錄到棋盤上

            pos = board.getNextPosition(pos); // 下一個(gè)滾動(dòng)位置

            switch (board.nextDirection[x][y]) { // 下一個(gè)方向往哪滾動(dòng)
            case 1:
                cube.rollUp();
                break;
            case 2:
                cube.rollDown();
                break;
            case 3:
                cube.rollLeft();
                break;
            case 4:
                cube.rollRight();
                break;
            }

            // 滾動(dòng)到下一個(gè)位置
            x = pos.x;
            y = pos.y;

        }

        // 上面while循環(huán)跳出時(shí),立方體在終點(diǎn)沒有將底面的值記錄到棋盤上
        // 在這里記錄
        board.board[x][y] = String.valueOf(cube.down).charAt(0);

        board.printBoard();

    }

}

示例輸入的結(jié)果:

6 2 1 5 . 
. . . 3 . 
1 2 . 2 6 
. 4 . . 4 
. 5 6 2 1 

測試用例輸入:

5
# # # # #
# . . . #
# . S # #
# . . . .
# # # # E

預(yù)期輸出:

6 5 1 2 6
4 . . . 4
1 . 6 2 1
3 . . . .
6 5 1 2 6

程序輸出:

6 5 1 2 6 
4 . . . 4 
1 . 6 2 1 
3 . . . . 
6 5 1 2 6 
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容