棋盘完全覆盖

  • 一、问题解答
  • (一)问题描述

用2×1或1×2的骨牌把m×n的棋盘完全覆盖是一个很容易解决的问题。那么,能不能把完全覆盖的种数求出来,会不会很复杂呢?

(二)要求

给定任意m行n列的棋盘,编写程序求出使用2×1或1×2的骨牌对棋盘进行完全覆盖有多少种不同的方法。

二、问题解答

(一)设计思路

1.

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
棋盘覆盖问题是指在一个大小为2^n * 2^n的正方形棋盘中,有一个方格被去掉(如下图所示),现在需要用L型骨牌(类似于多米诺骨牌,由两个小正方形组成,形状如“L”)将棋盘完全覆盖,求覆盖方案。 ![棋盘覆盖问题示意图](https://img-blog.csdn.net/20150923193807438) MFC是微软基于Windows API的一个应用框架,用于快速开发Windows桌面应用程序。实现棋盘覆盖问题需要使用递归算法,MFC可以很方便地实现递归算法,以下是一个简单的MFC程序实现棋盘覆盖问题: 1. 创建一个MFC应用程序,选择对话框为基础模板。 2. 在对话框中添加一个按钮,用于触发覆盖棋盘的操作。 3. 在对话框类的头文件中添加以下代码: ```cpp #define MAXN 1024 // 棋盘大小的最大值 int board[MAXN][MAXN]; // 棋盘 int tile = 1; // 骨牌编号 ``` 4. 在对话框类的.cpp文件中添加以下代码: ```cpp // 将区域(x1, y1)~(x2, y2)覆盖成L型骨牌,除了(r, c)这个位置 void cover(int x1, int y1, int x2, int y2, int r, int c) { if (x1 == x2 && y1 == y2) return; // 区域大小为1,不需要覆盖 int s = tile++; // 当前使用的骨牌编号 int xm = (x1 + x2) / 2, ym = (y1 + y2) / 2; // 中心点坐标 // 覆盖左上角区域 if (r <= xm && c <= ym) cover(x1, y1, xm, ym, r, c); else { board[xm][ym] = s; // 覆盖其余三个区域 cover(x1, y1, xm, ym, xm, ym); if (r <= xm && c > ym) cover(x1, ym + 1, xm, y2, r, c); if (r > xm && c <= ym) cover(xm + 1, y1, x2, ym, r, c); if (r > xm && c > ym) cover(xm + 1, ym + 1, x2, y2, r, c); } // 覆盖右上角区域 if (r <= xm && c > ym) cover(x1, ym + 1, xm, y2, r, c); else { board[xm][ym + 1] = s; // 覆盖其余三个区域 if (r <= xm && c <= ym) cover(x1, y1, xm, ym, xm, ym); cover(x1, ym + 1, xm, y2, xm, ym + 1); if (r > xm && c <= ym) cover(xm + 1, y1, x2, ym, r, c); if (r > xm && c > ym) cover(xm + 1, ym + 1, x2, y2, r, c); } // 覆盖左下角区域 if (r > xm && c <= ym) cover(xm + 1, y1, x2, ym, r, c); else { board[xm + 1][ym] = s; // 覆盖其余三个区域 if (r <= xm && c <= ym) cover(x1, y1, xm, ym, xm + 1, ym); if (r <= xm && c > ym) cover(x1, ym + 1, xm, y2, xm + 1, ym); cover(xm + 1, y1, x2, ym, xm + 1, ym); if (r > xm && c > ym) cover(xm + 1, ym + 1, x2, y2, r, c); } // 覆盖右下角区域 if (r > xm && c > ym) cover(xm + 1, ym + 1, x2, y2, r, c); else { board[xm + 1][ym + 1] = s; // 覆盖其余三个区域 if (r <= xm && c <= ym) cover(x1, y1, xm, ym, xm + 1, ym + 1); if (r <= xm && c > ym) cover(x1, ym + 1, xm, y2, xm + 1, ym + 1); if (r > xm && c <= ym) cover(xm + 1, y1, x2, ym, xm + 1, ym + 1); cover(xm + 1, ym + 1, x2, y2, xm + 1, ym + 1); } } // 初始化棋盘 void init_board(int n, int r, int c) { memset(board, -1, sizeof(board)); board[r][c] = 0; // 空白位置 tile = 1; } // 绘制棋盘 void draw_board(CDC* pDC, int n, int x, int y, int w) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (board[i][j] == -1) pDC->FillSolidRect(x + j * w, y + i * w, w, w, RGB(255, 255, 255)); // 白色 else if (board[i][j] == 0) pDC->FillSolidRect(x + j * w, y + i * w, w, w, RGB(0, 0, 0)); // 黑色 else pDC->FillSolidRect(x + j * w, y + i * w, w, w, RGB(255, 0, 0)); // 其他颜色 } } } // 覆盖棋盘 void cover_board(int n, int r, int c) { init_board(n, r, c); cover(0, 0, n - 1, n - 1, r, c); } // 棋盘覆盖操作 void CMyDlg::OnBnClickedButton1() { int n = 8; // 棋盘大小 int r = rand() % n, c = rand() % n; // 随机取一个空白位置 cover_board(n, r, c); // 覆盖棋盘 CClientDC dc(this); draw_board(&dc, n, 10, 50, 30); // 绘制棋盘 } ``` 在上述代码中,`cover()`函数使用递归算法实现棋盘覆盖,`init_board()`函数用于初始化棋盘,`draw_board()`函数用于绘制棋盘。在点击按钮时,调用`cover_board()`函数进行棋盘覆盖,然后调用`draw_board()`函数绘制棋盘。运行程序后,每次点击按钮都会生成一个随机的空白位置,并用L型骨牌覆盖棋盘

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值