「算法設計與分析」棋盤覆蓋+視頻講解

題目分析

在一個 2k*2k 個方格組成的棋盤中,若恰有一個方格與其他方格不同,則稱該方格爲一個特殊方格,且稱棋盤爲特殊棋盤。
在棋盤覆蓋問題中,要用到4中不同形態的L型骨牌覆蓋一個給定的特殊棋盤上除特殊方格意外的所有方格,且任何2個L型骨牌不得重疊覆蓋。

分治法

分治法的基本思想

視頻講解

超簡單!棋盤覆蓋+代碼實現

代碼

public class qipan {
    int tile = 1;//表示L型骨牌的編號
    int[][] board = new int[100][100];//表示棋盤

    //處理帶有特殊棋子的棋盤.tr、tc表示棋盤的入口即左上角的行列號,dr、dc表示特殊棋子的行列位置,size表示棋盤的大小
    public void ChessBoard(int tr, int tc, int dr, int dc, int size) {
        if (size == 1) {  //如果棋盤大小=1,就說明不能再進行劃分
            return;       //即到達遞歸邊界  返回  退出方法
        }
        int t = tile++;   
        int s = size / 2;//每一次化大棋盤爲一半的子棋盤
        //要處理帶有特殊棋子的棋盤,第一步先處理左上棋盤
        if (dr < tr + s && dc < tc + s)//左上角子棋盤有特殊棋子
        {
            ChessBoard(tr, tc, dr, dc, s);
        }//處理有特殊棋子的左上角子棋盤
        else//處理無特殊棋子的左上角子棋盤
        {
          //設左上角子棋盤的右下角爲特殊棋子,用t型的骨牌覆蓋。
            board[tr + s - 1][tc + s - 1] = t;
            ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);//處理有用骨牌覆蓋的格子作爲特殊棋子的左上角子棋盤
        }

        //第二步處理右上角棋盤
        if (dr < tr + s && dc >= tc + s)//右上角子棋盤有特殊棋子
        {
            ChessBoard(tr, tc + s, dr, dc, s);//處理有特殊棋子的右上角子棋盤
        } else {
            board[tr + s - 1][tc + s] = t;//設右上角子棋盤的左下角爲特殊棋子,用t型的骨牌覆蓋。
            ChessBoard(tr, tc + s, tr + s - 1, tc + s, s);//處理有用骨牌覆蓋的格子作爲特殊棋子的右上角子棋盤
        }

        //第三步處理左下角子棋盤
        if (dr >= tr + s && dc < tc + s)//左下角子棋盤有特殊棋子
        {
            ChessBoard(tr + s, tc, dr, dc, s);//處理有特殊棋子的左下角子棋盤
        } else {
            board[tr + s][tc + s - 1] = t;//設左下角子棋盤的右上角爲特殊棋子,用t型的骨牌覆蓋。
            ChessBoard(tr + s, tc, tr + s, tc + s - 1, s);//處理有用骨牌覆蓋的格子作爲特殊棋子的左下角子棋盤
        }

        //第四步處理右下角棋盤
        if (dr >= tr + s && dc >= tc + s)//右下角子棋盤有特殊棋子
        {
            ChessBoard(tr + s, tc + s, dr, dc, s);//處理有特殊棋子的右下角子棋盤
        } else {
            board[tr + s][tc + s] = t;//設子棋盤右下角的左上角爲特殊棋子,用t型的骨牌覆蓋。
            ChessBoard(tr + s, tc + s, tr + s, tc + s, s);//處理有用 骨牌覆蓋的格子作爲特殊棋子的右下角子棋盤
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
		System.out.println("請輸入棋盤的大小(size)");
		int size = sc.nextInt();   //棋盤大小
		System.out.println("請輸入特殊棋子的位置(dr,dc)");
        int dr = sc.nextInt();   
        int dc = sc.nextInt();    
        //調用方法
        qipan c = new qipan();
        //(0,0)左上角的方格位置 (dr,dc特殊方格位置) size棋盤大小
        c.ChessBoard(0, 0, dr, dc, size);  
        //輸出棋盤
        for (int i = 0; i < size; i++) {
            for(int j = 0; j < size; j++) {
                System.out.print(String.format("%5d", c.board[i][j]));
            }
            System.out.println();

    }
    }
}

代碼截圖

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章