zoukankan      html  css  js  c++  java
  • 算法设计与分析——棋盘覆盖问题(分治算法)

    在一个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是地图的列号,

    所以写的时候一开始预想的填图顺序为左上,右上,左下,右下,实际出来的顺序是左上,左下,右上,右下

        

  • 相关阅读:
    input上传限定文件类型
    扫描二维码自动识别手机系统(Android/IOS)
    css/html/Javascript
    移动端容易碰到的点击穿透的坑
    洛谷P3387 【模板】缩点
    洛谷P1137 旅行计划
    洛谷P2324 [SCOI2005]骑士精神
    洛谷P2571 [SCOI2010]传送带
    BZOJ4300: 绝世好题
    [洛谷P1966] 火柴排队
  • 原文地址:https://www.cnblogs.com/davion2017/p/12494227.html
Copyright © 2011-2022 走看看