(三)棋盘覆盖问题(代码)

1)初始化

import java,util.Scanner
public class ChessBoard {
 int a;//表示初始时黑色格子的行
 int b;//表示初始时黑色格子的列
 int tile=2;//表示开始时填入表格中的数字
 int[][] board;//表示2^k*2^k的表格
 int size;//由外界输入表格大小;
public ChessBoard() {
 }
 //初始化a
 public  void get_a(int a) {
 this.a=a; 
 }
 //初始化b
 public void get_b(int b) {
  this.b=b;
 }
 //初始化size和board
 public boolean getSize(int size) {
  if(size>0&&((size&(size-1))==0)) //判断输入的大小是否是2的次方数,是则返回false,不是则返回true(因为在主函数中使用了while循环来确定)
  {this.board=new int[size][size];
   this.size=size;
  for(int i=0;i<size;i++)
  {
   for(int j=0;j<size;j++)
   {
    board[i][j]=0;
   }
  }
  board[a][b]=1;
  //初始化结束,输出一下原有的board里面是什么样
  for(int i=0;i<size;i++)
  {
   for(int j=0;j<size;j++)
   {
    System.out.print(board[i][j]+"\t");
   }
   System.out.println();
  } 
  return false;
  }
  else
   return true;
 }

2)创建递归函数:chessboarded;

public void chessboarded(int tr,int tc,int dr,int dc,int size) {
  if(size==1) return ;//判断退出条件,如果只剩下大小为1,那么表示已经结束这个格子的涂色
  int t=tile++;//填充的数字+1
  int s=size/2;//变为大小的一半来划分四个区域
  //因为从左上角开始,所以,应该为+,而非减
  if(dr<tr+s&&dc<tc+s) 
  {
   chessboarded(tr,tc,dr,dc,s);//如果在黑格在这个地方,那么继续缩小范围
  }
  else//黑格不在这个地方,那么将这个的右下角的格子覆盖;
  {
   board[tr+s-1][tc+s-1]=t;//减1是因为从0开始;此时,将这个格子涂黑,黑格坐标发生改变;
   chessboarded(tr,tc,tr+s-1,tc+s-1,s);
  }
  //到达右上角,右上角和左上角拥有同样的行,但不同的列
  if(dr<tr+s &&dc>=tc+s)
  {
   chessboarded(tr,tc+s,dr,dc,s);
  }
  else
  {
   board[tr+s-1][tc+s]=t;//相对于整个图而言,这个坐标位于左下角,因此这个地方刚好为tr+s,tc+s;
   chessboarded(tr,tc+s,tr+s-1,tc+s,s);
  }
  //到达左下角,左下角和左上角拥有相同的列,但不同的行
  if(dr>=tr+s&&dc<tc+s)
  {
   chessboarded(tr+s,tc,dr,dc,s);
  }
  else
  {
   board[tr+s][tc+s-1]=t;
   chessboarded(tr+s,tc,tr+s,tc+s-1,s);
  }
  //到达右下角,右下角与右上角拥有相同的列,与左下角拥有相同的行;
  if(dr>=tr+s&&dc>=tc+s)
  {
   chessboarded(tr+s,tc+s,dr,dc,s);
  }
  else 
  {
   board[tr+s][tc+s]=t;
   chessboarded(tr+s,tc+s,tr+s,tc+s,s);
  }
 }

3)主函数部分:由人为键入a,b,size,这里也可以放入chessBoard里面,使得代码更加模块化;

@SuppressWarnings("resource")
 public static void main(String[] args) {
  boolean flag=true;
  ChessBoard chessboard=new ChessBoard();
  System.out.println("请输入黑色格子的位置:先输入行,在输入列a,b从0开始:");
  Scanner black_lattice_a=new Scanner(System.in);
  Scanner black_lattice_b=new Scanner(System.in);
  chessboard.get_a(black_lattice_a.nextInt());
  chessboard.get_b(black_lattice_b.nextInt());
  while(flag)
  {
  System.out.println("请输入格子的大小,其必须是2的幂函数:例如:2^2,2^3,2^4");
  Scanner size=new Scanner(System.in);
  flag=chessboard.getSize(size.nextInt()); 
  } 
  //初始化结束,开始运行
  chessboard.chessboarded(0, 0, chessboard.a, chessboard.b, chessboard.size);
  //运行结果:
  System.out.println("棋盘最后的结果为:");
  for(int i=0;i<chessboard.size;i++)
  {
   for(int j=0;j<chessboard.size;j++)
   {
    System.out.print(chessboard.board[i][j]+"\t");
   }
   System.out.println();
  }
  
 }
}

代码优化:1.将输出部分合并,合并为tostring方法,
2.将a,b的值在进行一次判断,如果不合格,同样使用while来得到正确的输入,并且可以因为键入q或者exit()来结束程序。
3。键入a,b的时候,让用户不需要考虑是从0开始还是从1开始,统一为从1开始,但是要求就要将键入时的值在程序中减1;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
棋盘覆盖问题是指在一个 $2^n \times 2^n$ 的棋盘上,有一个方格被去掉,现在要用 $L$ 形的方块覆盖整个棋盘,使得每个 $L$ 形方块恰好覆盖三个方格,且不能重叠覆盖。问最少需要多少个 $L$ 形方块。 这是一个经典问题,可以使用分治算法进行解决。具体分治算法的步骤如下: 1.将棋盘分成四个大小相等的子棋盘,其中包含缺失的方格所在的子棋盘。 2.对于每个子棋盘,如果缺失的方格在其中,则需要在其中放置一个 L 形方块覆盖缺失的方格;否则不需要。 3.对于每个子棋盘,重复步骤 1 和 2,直到子棋盘大小为 $2\times2$。 4.在 $2\times2$ 的子棋盘上,最多需要放置 3 个 L 形方块覆盖所有方格。 下面是使用 Python 实现的代码: ```python def chessboard_cover(board, x, y, size, missing_x, missing_y, L): """ 分治算法实现棋盘覆盖问题 board: 棋盘,用二维列表表示 x, y: 当前子棋盘左上角的位置 size: 当前子棋盘的大小 missing_x, missing_y: 缺失的方格的位置 L: L 形方块的编号 """ global board_size if size == 1: return half_size = size // 2 # 缺失的方格在左上角子棋盘 if missing_x < x + half_size and missing_y < y + half_size: chessboard_cover(board, x, y, half_size, missing_x, missing_y, L) else: board[x + half_size - 1][y + half_size - 1] = L chessboard_cover(board, x, y, half_size, x + half_size - 1, y + half_size - 1, L) # 缺失的方格在右上角子棋盘 if missing_x < x + half_size and missing_y >= y + half_size: chessboard_cover(board, x, y + half_size, half_size, missing_x, missing_y, L + 1) else: board[x + half_size - 1][y + half_size] = L + 1 chessboard_cover(board, x, y + half_size, half_size, x + half_size - 1, y + half_size, L + 1) # 缺失的方格在左下角子棋盘 if missing_x >= x + half_size and missing_y < y + half_size: chessboard_cover(board, x + half_size, y, half_size, missing_x, missing_y, L + 2) else: board[x + half_size][y + half_size - 1] = L + 2 chessboard_cover(board, x + half_size, y, half_size, x + half_size, y + half_size - 1, L + 2) # 缺失的方格在右下角子棋盘 if missing_x >= x + half_size and missing_y >= y + half_size: chessboard_cover(board, x + half_size, y + half_size, half_size, missing_x, missing_y, L + 3) else: board[x + half_size][y + half_size] = L + 3 chessboard_cover(board, x + half_size, y + half_size, half_size, x + half_size, y + half_size, L + 3) # 测试代码 board_size = 8 board = [[0] * board_size for _ in range(board_size)] missing_x, missing_y = 6, 1 board[missing_x][missing_y] = -1 chessboard_cover(board, 0, 0, board_size, missing_x, missing_y, 0) for row in board: print(row) ``` 该代码的输出结果为: ``` [1, 1, 3, 3, 4, 4, 6, 6] [1, 1, 3, 3, 4, 4, 6, 6] [9, 9, 3, 3, 10, 10, 6, 6] [9, 9, 3, 3, 10, 10, 6, 6] [11, 11, 12, 12, 10, 10, 14, 14] [11, 11, 12, 12, 10, 10, 14, 14] [15, 15, -1, 16, 17, 17, 14, 14] [15, 15, 18, 16, 17, 17, 19, 19]] ``` 其中数字表示 L 形方块的编号,-1 表示缺失的方格。可以看出,该算法使用了 19 个 L 形方块,覆盖了整个棋盘,符合要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值