算法設計與分析——棋盤覆蓋問題(分治算法)


在一個2 ^k ×2^ k 個方格組成的棋盤中,恰有一個方格與其他方格不同,,稱該方格為一特殊方格,且稱該棋盤為一特殊棋盤。

在棋盤覆蓋問題中,要用圖示的4種不同形態的L型骨牌覆蓋給定的特殊棋盤上除特殊方格以外的所有方格,且任何2個L型骨牌不得重疊覆蓋。

        

思路如下,將棋盤十字分成4份為2^(k-1) x 2^(k-1)大小的小棋盤,其中特殊方格必在其中一個區域,另外三個區域則是完整空白的,

因此可以選用上訴L型骨牌中的一塊放在中間,恰好覆蓋到另外三個空白區域,如此,就變成了4個和最開始一樣的問題,然后又是中間十字分……

禁止套娃!!!

  

可以在白紙上畫一畫玩玩就明白了,然后我用的Java實現了一遍(其實就是大概抄了一下老師的課件)

 1 import java.util.Scanner;
 2 
 3 /**
 4  * @author: Davion
 5  * @date: 2020/3/14
 6  * @description: 棋盤覆蓋問題,分治算法
 7  */
 8 public class Chess {
 9     private static int title = 1;
10     private static int[][] border =new int[64][64];
11     public static void main(String[] args) {
12         Scanner scanner = new Scanner(System.in);
13         int size, dx, dy;
14         // 輸入對應數據
15         System.out.print("size:");
16         size = scanner.nextInt();
17         System.out.print("x, y:");
18         dx = scanner.nextInt();
19         dy = scanner.nextInt();
20 
21         // 設置特殊位置
22         border[dx][dy] = -1;
23         chessBord(0, 0, dx, dy, size);
24 
25         for (int i = 0; i < size; i++) {
26             for (int j = 0; j < size; j++) {
27                 System.out.printf("%3s", border[i][j]);
28             }
29             System.out.println();
30         }
31     }
32 
33     /**
34      *
35      * @param tx 左上x坐標
36      * @param ty 左上y坐標
37      * @param dx 不可覆蓋旗子x坐標
38      * @param dy 不可覆蓋旗子y坐標
39      * @param size 棋盤大小
40      */
41     private static void chessBord(int tx, int ty, int dx, int dy, int size){
42         if (size == 1){
43             return;
44         }
45         int t = title++;
46         int s = size / 2;
47         // 覆蓋左上
48         if (dx < tx + s && dy < ty + s) {
49             // 特殊點在左上
50             chessBord(tx, ty, dx, dy, s);
51         } else {
52             // 特殊點不在左上
53             border[tx + s - 1][ty + s - 1] = t;
54             chessBord(tx, ty, tx + s - 1, ty + s - 1, s);
55         }
56 
57         // 覆蓋左下
58         if (dx >= tx + s && dy < ty + s) {
59             chessBord(tx + s, ty, dx, dy, s);
60         } else {
61             border[tx + s][ty + s - 1] = t;
62             chessBord(tx + s, ty, tx + s, ty + s - 1, s);
63         }
64 
65         if (dx < tx + s && dy >= ty + s) {
66             chessBord(tx, ty + s, dx, dy, s);
67         } else{
68             border[tx + s - 1][ty + s] = t;
69             chessBord(tx, ty + s, tx + s - 1, ty + s, s);
70         }
71 
72         if (dx >= tx + s && dy >= ty + s) {
73             chessBord(tx + s, ty + s, dx, dy, s);
74         } else {
75             border[tx + s][ty + s] = t;
76             chessBord(tx + s, ty + s, tx + s, ty + s, s);
77         }
78     }
79 }
View Code

這里的x和y我搞混了,想的是平時數學用的橫向x,縱向y,實際上這里的x是指地圖的行號,y是地圖的列號,

所以寫的時候一開始預想的填圖順序為左上,右上,左下,右下,實際出來的順序是左上,左下,右上,右下

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM