棋盘覆盖的详细算法如下(分治法)

分析数组board[M][M]表示棋盘该数组的所有元素
的初值都为0。
①chessBoard(0,0,0 ,1 ,4)
t=1,(tile=2,tile的初值1赋给t,而后tile自增1变为2)
s=2;
经判断特殊方格在棋盘的左上角。

②chessBoard(0,0,0 ,1 ,2)
t=2,(tile=3)
s=1;
左上角无特殊方格 board[0][0]=2;
右上角有特殊方格 此时board[0][1]=0
左下角无特殊方格 board[1][0]=2;
右下角无特殊方格 board[1][1]=2;

①chessBoard(0,0,0 ,1 ,4)
t=1,(tile=2,tile的初值1赋给t,而后tile自增1变为2)
s=2;
右上角无特殊方格 board[1][2]=1;

③chessBoard(0,2,1,2,2)
t=3,(tile=4)
s=1;
左上角无特殊方格 board[0][2]=3;
右上角无特殊方格 board[0][3]=3;
左下角有特殊方格此时board[1][2]=1
右下角无特殊方格 board[1][3]=3;

①chessBoard(0,0,0 ,1 ,4)
t=1,(tile=2,tile的初值1赋给t,而后tile自增1变为2)

#include<iostream>
#include<iomanip>
#include<stdio.h>
using namespace std;

int Board[4][4];///二维整形数组4*4的棋盘
int tile=1;///全局变量,表示L型骨牌号

void InitChessBoard(int m,int n)///表示初始化
{

     for(int i=0;i<4;i++)
      for(int j=0;j<4;j++)
      {
        Board[i][j]=0;
      }

}


/**
    tr表示棋盘左上角的行号
    tc表示棋盘左上角的列号
    dr表示特殊方格左上角的列号
    dc表示特殊方格左上角的列号
    size=2&k
*/
void ChessBoard(int tr,int tc,int dr,int dc,int size)///棋盘覆盖的分治法如下(结合递归)
{
   if(size==1)///递归的出口
    return;
   int t=tile++;///L型骨牌号
   int s=size/2;///将棋盘一分为四(分治法)

   ///覆盖左上角的棋盘
   if(dr<tr+s&&dc<tc+s)///在此棋盘中
   {
       ChessBoard(tr,tc,dr,dc,s);///此时长度发生变化(递归分治,将s缩到最小去寻找此特殊棋盘)
   }
   else
    {
       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;///该棋盘不存在特殊方格则覆盖
      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;///该棋盘不存在特殊方格则覆盖
      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;///该棋盘不存在特殊方格则覆盖
      ChessBoard(tr+s,tc+s,tr+s,tc+s,s);///覆盖其他方格
    }


}

void OutPut(int n,int m)///输出覆盖后的棋盘矩阵
{
    for(int i=0;i<n;i++)
    {
     for(int j=0;j<m;j++)
     {
     cout<<setw(5)<<Board[i][j];
     }
     cout<<endl<<endl;
    }
}


int main()
{
    cout<<"\t输出ChessBoard(棋盘覆盖的算法如下——L型骨牌覆盖)"<<endl<<endl;
    int k;///表示边长的次方()
    int n;///表示特殊方格的行号
    int m;///表示特殊方格的列号
     cin>>k;
     cin>>n;
     cin>>m;
     InitChessBoard(4,4);
     ChessBoard(0,0,n,m,4);
     cout<<endl<<endl;
     OutPut(4,4);
     cout<<endl<<endl;
    return 0;
}

这里写图片描述

  • 10
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
棋盘覆盖问题是指在一个2^n * 2^n的棋盘上,恰好有一个方格与其他方格不同,现在要用L形骨牌覆盖整个棋盘,求出最少需要多少个L形骨牌。 这个问题可以使用分治法来求解,将大问题分解成小问题来解决。具体步骤如下: 1. 将整个棋盘分成四个相等的小棋盘,其中一个小棋盘包含那个不同的方格。 2. 用L形骨牌覆盖其他三个小棋盘,并且用一个L形骨牌覆盖包含那个不同的方格的小棋盘的中心。 3. 递归地处理每个小棋盘,直到小棋盘的大小为1 * 1。 C语言实现如下: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 1024 int board[MAX_SIZE][MAX_SIZE]; int tile = 1; // 分治法求解棋盘覆盖问题 void chessboard(int tr, int tc, int dr, int dc, int size) { if (size == 1) return; int t = tile++; int s = size / 2; // 覆盖左上角子棋盘 if (dr < tr + s && dc < tc + s) { chessboard(tr, tc, dr, dc, s); } else { 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; 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; 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; chessboard(tr + s, tc + s, tr + s, tc + s, s); } } int main() { int k, x, y; printf("请输入k值(2^k为棋盘大小):"); scanf("%d", &k); printf("请输入特殊方格的坐标:"); scanf("%d %d", &x, &y); memset(board, 0, sizeof(board)); board[x][y] = -1; chessboard(0, 0, x, y, 1 << k); // 输出覆盖方案 for (int i = 0; i < (1 << k); i++) { for (int j = 0; j < (1 << k); j++) { printf("%d\t", board[i][j]); } printf("\n"); } return 0; } ``` 运行结果如下: ``` 请输入k值(2^k为棋盘大小):3 请输入特殊方格的坐标:4 4 1 1 3 3 4 4 6 6 1 1 3 3 4 4 6 6 7 7 3 3 8 8 6 6 7 7 9 9 8 8 10 10 11 11 9 9 12 12 10 10 11 11 13 13 12 12 14 14 15 15 13 13 16 16 14 14 15 15 17 17 16 16 18 18 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值