Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 995|回复: 0

[算法学习]棋盘覆盖问题java解答

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-30 00:06:53 | 显示全部楼层 |阅读模式
    在一个2^k×2^k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有4^k种情形.因而对任何
    k≥0,有4^k种不同的特殊棋盘.
    下图中的特殊棋盘是当k=2时中的一种

    棋盘中的特殊方格如图


       使用以下四种L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖.如何覆盖?


       
      
       
       
         
       

         
       
      
    思路分析:
    当k>0时,将2^k×2^k棋盘分割为4个2^k-1×2^k-1子棋盘,如下图�图(3)所示:


        特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格.为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处。

    如下图所示,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而原问题转化为4个较小规模的棋盘覆盖问题.递归地使用这种分割,直至棋盘简化为1×1棋盘。



    (1)特殊方格在左上区域,那么其他几个区域的特殊方格可定,用如下一个L型骨牌覆盖3个无特殊方格的子棋盘会合处。

    (2)特殊方格在右上区域,那么其他几个区域的特殊方格可定,用如下一个L型骨牌覆盖3个无特殊方格的子棋盘会合处。


    (3)特殊方格在左下区域,那么其他几个区域的特殊方格可定,用如下一个L型骨牌覆盖3个无特殊方格的子棋盘会合处。

    (4)特殊方格在右下区域,那么其他几个区域的特殊方格可定,用如下一个L型骨牌覆盖3个无特殊方格的子棋盘会合处。

    java 代码:
    1. import java.util.Scanner;
    2. public class chessBoard
    3. {   
    4. private  int dr,dc,size; // dr: 特殊方格的排号。dc: 特殊方格的列号。size:棋盘规格
    5. private  int[][]board;

    6. public chessBoard(int size,int dc,int dr){
    7.   this.size=size;
    8.   this.dc=dc;
    9.   this.dr=dr;
    10.   board=new int[this.size][this.size];
    11.   init();
    12. }

    13. private void init() {
    14.   for(int i=0;i< size;i++)
    15.    for(int j=0;j< size;j++) board[i][j]=0;
    16. }

    17. public void chessBoard(int tr,int tc,int dr,int dc,int size){
    18.   if(size==1) return;
    19.   int s=size/2;
    20.      //特殊方格在左上角
    21.   if(dr< tr+s && dc< tc+s){//覆盖第四个L型骨牌
    22.    board[tr+s-1][tc+s]=4; //右上
    23.    board[tr+s][tc+s-1]=4;//左下
    24.    board[tr+s][tc+s]=4;//右下
    25.    chessBoard(tr,tc,dr,dc,s);//左上
    26.    chessBoard(tr,tc+s,tr+s-1,tc+s,s);//右上
    27.    chessBoard(tr+s,tc,tr+s,tc+s-1,s);//左下
    28.    chessBoard(tr+s,tc+s,tr+s,tc+s,s);//右下
    29.   }
    30.      //特殊方格在右上角
    31.   if(dr< tr+s && dc>=tc+s){//覆盖第3个L型骨牌
    32.    board[tr+s-1][tc+s-1]=3; //左上
    33.    board[tr+s][tc+s-1]=3;//左下
    34.    board[tr+s][tc+s]=3;//右下
    35.    chessBoard(tr,tc,tr+s-1,tc+s-1,s);//左上
    36.    chessBoard(tr,tc+s,dr,dc,s);   //右上
    37.    chessBoard(tr+s,tc,tr+s,tc+s-1,s);//左下
    38.    chessBoard(tr+s,tc+s,tr+s,tc+s,s);//右下
    39.   }
    40.      //特殊方格在左下角
    41.   if(dr>=tr+s && dc< tc+s){//覆盖第2个L型骨牌
    42.    board[tr+s-1][tc+s-1]=2; //左上
    43.    board[tr+s-1][tc+s]=2;//右上
    44.    board[tr+s][tc+s]=2;//右下
    45.    chessBoard(tr,tc,tr+s-1,tc+s-1,s);//左上
    46.    chessBoard(tr,tc+s,tr+s-1,tc+s,s);//右上
    47.    chessBoard(tr+s,tc,dr,dc,s);//左下
    48.    chessBoard(tr+s,tc+s,tr+s,tc+s,s);//右下
    49.    }
    50.      //特殊方格在右下角
    51.   if(dr>=tr+s && dc>=tc+s){//覆盖第1个L型骨牌
    52.    board[tr+s-1][tc+s-1]=1; //左上
    53.    board[tr+s-1][tc+s]=1;//右上
    54.    board[tr+s][tc+s-1]=1;//左下
    55.    chessBoard(tr,tc,tr+s-1,tc+s-1,s);//左上
    56.    chessBoard(tr,tc+s,tr+s-1,tc+s,s);//右上
    57.    chessBoard(tr+s,tc,tr+s,tc+s-1,s);//左下
    58.    chessBoard(tr+s,tc+s,dr,dc,s);//右下
    59.   }
    60. }

    61. public void showChess(){
    62.   for (int i = 0; i < size; i++) {
    63.    for (int j = 0; j < size; j++)
    64.    { System.out.print(board[i][j]+" ");}
    65.    System.out.println();       }
    66. }

    67. public static void main(String[] args) {
    68.   int size,dr,dc;
    69.         System.out.println("请输入棋盘的边长 ");
    70.         Scanner reader= new Scanner(System.in);
    71.   size=reader.nextInt(); //边长(4的倍数)
    72.   System.out.println("请输入棋盘特殊方格的具体位置(排号    列号):");
    73.   dr=reader.nextInt()-1; //排号
    74.   dc=reader.nextInt()-1; //列号
    75.   chessBoard chess=new chessBoard(size,dr,dc);
    76.   chess.chessBoard(0, 0, dr, dc, size);
    77.   chess.showChess();}
    78. }
    复制代码
    运行结果:


    另有图形界面的程序(请下载)




      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/11/30/000653000.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 04:03 , Processed in 0.379150 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表