编程大作业(棋盘覆盖问题)
棋盘覆盖问题程序说明
棋盘覆盖问题
对一M*N棋盘,假设有外形完全一样的骨排.每一骨排可覆盖棋盘上两相邻的方格.若用一些骨排覆盖棋盘,使棋盘上所有格被盖,且不交叉,称完全覆盖,.8*8棋盘是否可以完全覆盖?
编程思想:将棋盘设为一个M*N数组,对数组中每个元素分别赋值0和1,并使每个元素与其周围元素的值不相等。
再将数组中对角元素赋给0,1以外的值。
统计数组中0元素与1元素的个数。
若相等,证明可以完全覆盖,不相等则不能完全覆盖。
本程序特点:棋盘的行数和列数可以是任意的。
只需输入行数和列数便可得到结论。
缺点:棋盘只能是缺少对角的,不能是缺少任意的几格。
棋盘覆盖问题..txt - 记事本
#include <iostream>using namespace std;#define SIZE 4int title = 1; //title表示L型骨牌的编号int board[SIZE][SIZE];void ChessBoard(int tr,int tc,int dr,int dc,int size);void ChessPrint();int main(int argc,char * argv[]){char again = 'Y';int dr,dc;while(again=='Y'||again=='y'){cout<<"输入特殊方格所在的行号dr和列号dc:";cin>>dr>>dc;ChessBoard(0,0,dr-1,dc-1,SIZE);cout<<"覆盖结果为:"<<endl;ChessPrint();cout<<"继续?(Y||y)";cin>>again;}return 0;}/*** 功能:棋盘覆盖* @param tr表示棋盘左上角行号* @param tc表示棋盘左上角列号* @param dr表示特殊棋盘的行号* @param dc表示特殊棋盘的列号* @param size = 2^k* 棋盘的规格为2^k * 2^k**/void ChessBoard(int tr,int tc,int dr,int dc,int size){if(1 == size) return;int t = title++; //L型骨牌号int s = size / 2; //分割棋盘//覆盖左上角子棋盘if(dr < tr + s && dc < tc + s)//特殊方格在此棋盘中ChessBoard(tr, tc, dr, dc, s);else{//此棋盘无特殊方格//用t号L型骨牌覆盖右下角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);第 1 页else{//此子棋盘中无特殊方格//用t号L型骨牌覆盖左下角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{//用t号L型骨牌覆盖右上角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{//用t号L型骨牌覆盖左上角board[tr + s][tc + s] = t;//覆盖其余方格ChessBoard(tr + s, tc + s, tr + s, tc + s, s); }}//打印void ChessPrint(){int i;int j;for(i = 0; i < SIZE; i++){for(j = 0; j < SIZE; j++){cout<<board[i][j]<<" ";}cout<<endl;}}第 2 页。
【IT专家】递归分治策略——Java之棋盘覆盖问题解决
递归分治策略——Java之棋盘覆盖问题解决2018/03/23 35 问题描述与分析:在一个2的k次方乘以2的k次方个方格组成的棋盘中,若恰有一个方格与其他方格不同,则称该方格为一个特殊方格,且称该棋盘为一个特殊棋盘。
显然特殊方格在棋盘上出现的位置有4的k次方种情形。
因为对任何k =0,有4的k次方种不同的特殊棋盘。
如图(a)所示。
在棋盘覆盖问题中,要用4种不同形态的L型骨牌(b图所示)覆盖一个给定的特殊棋盘上除特殊方格以外所有方格,且任何2个L型骨牌不得重叠覆盖。
易知,在任何一个个2的k次方乘以2的k次方的棋盘覆盖中,用到的L型骨牌个数恰为(4的k次方-1)/3。
分治策略:当k 0时,将个2的k次方乘以2的k次方棋盘分割为4个2的(k-1)次方乘以2的(k-1)次方子棋盘。
特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘无特殊方格。
为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,这三个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题转化为4个较小规模的棋盘覆盖问题。
递归地使用这种分割,直至棋盘简化为1×1棋盘。
(示例图如下) 算法设计与实现:import java.util.Scanner;import java.math.*;public class ChessBoard { static int tile = 1; //表示L型骨牌的编号static int Board[][]; //表示棋盘,Board[0][0]是棋盘左上角方格。
/*声明:* 棋盘左上角方格的行号tr * 棋牌左上角方格的列号tc * 特殊方格所在的行号dr * 特殊方格所在的列号dc * size=2的k次方,棋盘规格为2的k次方乘以2的k次方static int tr,tc = 0; static int dr,dc,size; static double k; static 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); } else { // 此棋盘中无特殊方格// 用t号L型骨牌覆盖右下角Board[tr + s - 1][tc + s - 1] = t; // 覆盖其余方。
棋盘覆盖问题c语言
// 覆盖本子棋盘中的其余方格
ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
}
//覆盖右上角子棋盘
if(dr<tr+s&&dc>=tc+s)
// 特殊方格在此棋盘中
ChessBoard(tr,tc,dr,dc,s);
else
{//特此棋盘中无特殊方格 ,t号L型骨牌覆盖左下角
{//此棋盘中无特殊方格 ,t号L型骨牌覆盖左上角
board[tr+s][tc+s]=t;
// 覆盖本子棋盘中的其余方格
ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
}
}
int main()
{
int size,r,c,row,col;
printf("输入棋盘大小:\n");
scanf("%d",&size);//输入棋盘大小
{
for (c = 0; c < size; c++)
{
printf("%d ",board[r][c]);
}
printf("\n");
}
return 0;
}
运行效果:
实验报告成绩
老师
注:1)专业班级按打印课表中名称填写;2)课程名称按课表中名称填写,不能简写;
3)实验日期格式示例:)实验时间格式示例:“第三大节”5)实验情况包括任务(或题目)、解决方案(或者代码)、结果等;6)实验报告成绩按五级标准评分;精心搜集整理,只为你的需要
分治策略算法棋盘覆盖问题
在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其它方格,如何覆盖。
四个L型骨牌如下图1图1棋盘中的特殊方格如图2图2实现的基本原理是将2^k * 2^k的棋盘分成四块2^(k - 1) * 2^(k - 1)的子棋盘,特殊方格一定在其中的一个子棋盘中,如果特殊方格在某一个子棋盘中,继续递归处理这个子棋盘,直到这个子棋盘中只有一个方格为止如果特殊方格不在某一个子棋盘中,将这个子棋盘中的相应的位置设为骨牌号,将这个无特殊方格的了棋盘转换为有特殊方格的子棋盘,然后再递归处理这个子棋盘。
原理如图3所示。
图3将棋盘保存在一个二维数组中。
骨牌号从1开始,特殊方格为0,如果是一个4 * 4的棋盘,特殊方格为(2,2),那么程序的输出为2 23 32 1 1 34 1 0 54 45 5相同数字的为同一骨牌。
下面是棋盘覆盖问题的c++语言实现。
#include <iostream>#include<iomanip>using namespace std;#define BOARD_SIZE 4int board[BOARD_SIZE][BOARD_SIZE];// c1, r1: 棋盘左上角的行号和列号// c2, r2: 特殊方格的行号和列号// size = 2 ^ kvoid chessboard(int r1, int c1, int r2, int c2, int size){if(1 == size) return;int half_size;static int domino_num = 1;int d = domino_num++;half_size = size / 2;if(r2 < r1 + half_size && c2 < c1 + half_size) //特殊方格在左上角子棋盘chessboard(r1, c1, r2, c2, half_size);else // 不在此棋盘,将此棋盘右下角设为相应的骨牌号{ board[r1 + half_size - 1][c1 + half_size - 1] = d;chessboard(r1, c1, r1 + half_size - 1, c1 + half_size - 1, half_size);}if(r2 < r1 + half_size && c2 >= c1 + half_size) //特殊方格在右上角子棋盘chessboard(r1, c1 + half_size, r2, c2, half_size);else // 不在此棋盘,将此棋盘左下角设为相应的骨牌号{ board[r1 + half_size - 1][c1 + half_size] = d;chessboard(r1, c1 + half_size, r1 + half_size - 1, c1 + half_size, half_size);}if(r2 >= r1 + half_size && c2 < c1 + half_size) //特殊方格在左下角子棋盘chessboard(r1 + half_size, c1, r2, c2, half_size);else // 不在此棋盘,将此棋盘右上角设为相应的骨牌号{ board[r1 + half_size][c1 + half_size - 1] = d;chessboard(r1 + half_size, c1, r1 + half_size, c1 + half_size - 1, half_size);}if(r2 >= r1 + half_size && c2 >= c1 + half_size) //特殊方格在左上角子棋盘chessboard(r1 + half_size, c1 + half_size, r2, c2, half_size);else // 不在此棋盘,将此棋盘左上角设为相应的骨牌号{ board[r1 + half_size][c1 + half_size] = d;chessboard(r1 + half_size, c1 + half_size, r1 + half_size, c1 + half_size, half_size);}}void main(){ int i, j;board[2][2] = 0;chessboard(0, 0, 2, 2, BOARD_SIZE);for(i = 0; i < BOARD_SIZE; i++){ for(j = 0; j < BOARD_SIZE; j++)cout<<setw(4)<<board[i][j];cout<<"\n";}}。
棋盘覆盖实验报告
int x_pos;//特殊点横坐标
int y_pos;//特殊点竖坐标
Container p;
public MyChessBoard() {
super();
x_pos = 0;
y_pos = 0;
dimen = 0;
setTitle("棋盘覆盖");
setBackground(Color.YELLOW);
y = 0;}setLocation(x, y);}public void actionPerformed(ActionEvent e) {
if(e.getActionCommand()=="退出") {
System.exit
(0);}else if(e.getActionCommand()=="开始") {
x_pos = (int)(dimen*Math.random());//随机生成特殊点位置
y_pos = (int)(dimen*Math.random());
p.setLayout(new GridLayout(dimen, dimen));
System.out.println(x_pos+","+y_pos);
/**** @authorxxxx
*/
public class FenZi {
public static void main(String args[]){new MyChessBoard();}}
class MyChessBoard extends JFrame implements ActionListener {
for(int j=0; j<board[i].length; j++) {
3算法设计实验1棋盘覆盖
棋盘
骨牌
ห้องสมุดไป่ตู้
输入、输出
实验目标
• 要求 1.至少运行3组不同的输入数据; 2.用分治法求解. • 实验报告应包括 1. 题目; 2. 解决思想、方法阐述; 3. 实验结果截图; 4. 算法分析(时间复杂度推导); 5. 小结和心得; 6. 源程序清单. • 实验报告提交电子版,于第六周上课前发送至
算法分析与设计 实验 1
分治法
题目:棋盘覆盖
• 问题描述:在一个2kx2k的棋盘中,有一个特殊方 格,要求用L型骨牌覆盖满除特殊方格外的所有其 他方格,且骨牌不得重叠.(骨牌可以旋转放置) • 输入:k值、特殊方格坐标 • 输出:骨牌放法.其中用0表示特殊方格,同一张 骨牌所占方格用同一个数字表示,不同骨牌用不 同数字.
棋盘覆盖实验报告
import java.util.*;
/**** @authorxxxx
*/
public class FenZi {
public static void main(String args[]){new MyChessBoard();}}
class MyChessBoard extends JFrame implements ActionListener {
tile = 0;}void coverMethod(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) {
coverMethod(tr,tc,dr,dc,s);
for(int j=0; j<board[i].length; j++) {
if(board[i][j] == 0) {
btn = new JButton("@");
btn.setFont(new Font("", Font.BOLD, 24));
btn.setForeground(Color.red);
}else {
board[tr+s-1][tc+s-1] = t;
coverMethod(tr,tc,tr+s-1,tc+s-1,s);}if(dr<tr+s && dc>=tc+s) {
C语言编程练习59:棋盘问题
C语⾔编程练习59:棋盘问题题⽬描述在⼀个给定形状的棋盘(形状可能是不规则的)上⾯摆放棋⼦,棋⼦没有区别。
要求摆放时任意的两个棋⼦不能放在棋盘中的同⼀⾏或者同⼀列,请编程求解对于给定形状和⼤⼩的棋盘,摆放k个棋⼦的所有可⾏的摆放⽅案C。
输⼊输⼊含有多组测试数据。
每组数据的第⼀⾏是两个正整数n和k,⽤⼀个空格隔开,表⽰了将在⼀个n*n的矩阵内描述棋盘,以及摆放棋⼦的数⽬。
(n<=8,k<=n)当n和k均为-1时表⽰输⼊结束。
随后的n⾏描述了棋盘的形状:每⾏有n个字符,其中 # 表⽰棋盘区域, . 表⽰空⽩区域(数据保证不出现多余的空⽩⾏或者空⽩列)。
输出对于每⼀组数据,给出⼀⾏输出,输出摆放的⽅案数⽬C(数据保证C<2^31)。
样例输⼊2 1#..#4 4...#..#..#..#...-1 -1样例输出21思路:从第⼀排开始摆,⼀排摆⼀个,标记摆的位置的列。
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;char s[9][9];int vis[50];int n,k;int ans;void dfs(int a,int b){if(b==0){ans++;return;}for(int i=a;i<n;i++){for(int j=0;j<n;j++){if(s[i][j]=='#'&&vis[j]==0){vis[j]=1;dfs(i+1,b-1);vis[j]=0;}else{continue;}}}}int main(){while(scanf("%d%d",&n,&k)!=EOF){if(n==-1&&k==-1){break;}for(int i=0;i<n;i++){scanf("%s",&s[i]);}memset(vis,0,sizeof(vis)); ans=0;dfs(0,k);printf("%d\n",ans);}}。
棋盘算法实验报告(3篇)
个人自我介绍简单大方
很抱歉,但我无法为您提供____字的自我介绍。
以下是一个简洁而大方的自我介绍示例,供您参考:
大家好,我叫[姓名]。
很高兴有机会向大家介绍一下自己。
我出生并长大在[所在地],是一个勤奋、积极向上的人。
在学业方面,我于[毕业时间]从[学校名称]获得了[学位/专业]学位。
在大学期间,我通过自我努力和课外学习,取得了良好的学术成绩,并参与了一些学生组织和社团活动。
这些经历不仅培养了我的团队合作和领导能力,也加强了我的沟通和组织能力。
在工作方面,我有[工作年限]年的相关工作经验。
我曾在[公司/组织名称]担任[职位],负责[工作职责]。
在这期间,我不断努力提升自己的专业知识和技能,以适应快速发展的工作环境。
我善于分析问题并找出解决方案,能够有效地与团队合作并承担责任,这些都为我赢得了同事和上级的认可。
除了工作,我也积极参与志愿者活动,希望能为社区和弱势群体做一点贡献。
我相信,通过奉献和关心他人,我们可以建立一个更加和谐和温暖的社会。
在个人生活中,我喜欢阅读、旅行和运动。
阅读扩展了我的视野,旅行让我能够体验不同的文化和风景,而运动则让我保持健康和积极的精神状态。
此外,我也很喜欢与家人和朋友相处,分享彼此的喜怒哀乐。
总的来说,我是一个热情、乐观、有责任心的人。
我相信勤奋和坚持可以取得成功,而真诚和善良可以赢得他人的信任和支持。
我希望能够在您的团队中发挥我的才能,并与大家一同成长和进步。
这就是我简单的自我介绍,谢谢大家!。
棋盘覆盖问题算法思路
棋盘覆盖问题算法思路棋盘覆盖问题是一个经典的递归问题,其原始问题定义如下:给定一个2^n*2^n的棋盘,其中一个方格被标记,将该棋盘分割成4个2^(n-1)*2^(n-1)的小棋盘,同时以递归的方式,将标记方格分割到4个小棋盘之一,并覆盖其他方格。
重复此过程,直到达到基本情况,即当棋盘大小为2*2,无需分割。
我们可以使用分治法来解决这个问题,即将一个大问题分解为多个小问题,并最终将它们的解组合起来得到原问题的解。
下面是一个算法思路:1.定义一个棋盘的类,表示一个棋盘对象。
其中包括棋盘的大小、标记方格的位置坐标等信息。
2. 定义一个递归函数cover(board, size, tr, tc, dr, dc),其中board表示当前的棋盘对象,size表示当前棋盘的大小,(tr, tc)表示当前棋盘左上角方格的坐标,(dr, dc)表示标记方格的坐标。
3.首先检查当前棋盘大小是否为2*2,如果是,则直接将标记方格的位置填充到其他3个方格,并返回。
4. 否则,将当前棋盘的大小减半,计算出当前棋盘分割后4个小棋盘的左上角方格坐标和标记方格的位置坐标(nt, nl, nr, nc)。
5. 然后分别递归调用cover函数对4个小棋盘进行覆盖,需要注意传递的参数:a. 对于第一个小棋盘,其大小为size / 2,左上角坐标为(tr, tc),标记方格的坐标为(nt, nl)。
b. 对于第二个小棋盘,其大小为size / 2,左上角坐标为(tr, tc + size / 2),标记方格的坐标为(nr, nc)。
c. 对于第三个小棋盘,其大小为size / 2,左上角坐标为(tr + size / 2, tc),标记方格的坐标为(nr, nc)。
d. 对于第四个小棋盘,其大小为size / 2,左上角坐标为(tr + size / 2, tc + size / 2),标记方格的坐标为(nt, nl)。
6.最后,将4个小棋盘的覆盖结果组合起来得到原问题的解,并将该结果填充到当前棋盘。
算法分析与设计实验1:棋盘覆盖
• 3.[实验说明,包括输入、输出、结果截图]
输入:交互式输入棋盘的长度,特殊棋盘的坐标
输出:棋盘由数字组成,采用不同数字代表不同坐标的L形骨牌,特殊棋盘上的数字为0
运行例1:
运行例2:
•4.[算法复杂性计算过程]
可以知道算法的递推公式为:
当k=0时,T(k)=O(1);当k>0时,T(k)=4T(k-1)+O(1);
chess(tr+half,tc,tr+half,tc+half-1,half)
if pr>=tr+half and pc>=tc+half:
chess(tr+half,tc+half,pr,pc,half)
else:
table[tr+half][tc+half]=count
chess(tr+half,tc+half,tr+half,tc+half,half)
chess(tr,tc,pr,pc,half)
else:
table[tr+half-1][tc+half-1]=count
chess(tr,tc,tr+half-1,tc+half-1,half)
if pr<tr+half and pc>=tc+half:
chess(tr,tc+half,pr,pc,half)
1.至少运行3组不同的输入数据;
2.用分治法求解
实验实现
• 1.[编程语言]:实验用Python完成算法设计和程序设计并调试通过。
• 2.[解题思想、方法]
棋盘覆盖问题的算法实现(代码及截图)
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 main() { int i,j,k,a,b; printf("请输入特殊方格的坐标:"); scanf("%d %d",&a,&b); ChessBoard(0,0,a,b,4); for(k=0;k<tile;k++) { printf("编号为%d的型骨牌的坐标为:",k); for(i=0;i<4;i++) for(j=0;j<4;j++) { if(Board[i][j]==k&&(i!=a||j!=b)) printf("(%d,%d)",i,j); } printf("\n"); } }
棋盘覆盖问题的算法实现
在一个2^k * 2^k个方格组成的棋盘中,有一个方格与其它的 不同,若使用以下四种L型骨牌覆盖除这个特殊方格的其它方 格,如何覆盖。 四个L型骨牌如下图1
算法设计--普通背包问题与棋盘覆盖问题分析
目录一、问题描述 (2)1、普通背包问题: (2)2、棋盘覆盖问题: (2)二、问题分析 (2)1、普通背包问题: (2)2、棋盘覆盖问题: (3)三、建立数学模型 (3)1、普通背包问题: (3)四、算法设计 (4)2、普通背包问题: (4)2、棋盘覆盖问题: (4)五、算法实现 (5)1、普通背包问题: (5)2、棋盘覆盖问题: (8)六、测试分析 (9)1、普通背包问题: (9)2、棋盘覆盖问题: (11)七、结论 (12)八、源程序 (12)1、普通背包问题: (12)2、棋盘覆盖问题: (15)九、参考文献: (16)一、问题描述1、普通背包问题:有一个背包容量为C,输入N个物品,每个物品有重量S[i],以及物品放入背包中所得的收益P[i]。
求选择放入的物品,不超过背包的容量,且得到的收益最好。
物品可以拆分,利用贪心算法解决。
2、棋盘覆盖问题:在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。
在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
二、问题分析1、普通背包问题:贪心算法的基本思想是:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的求得更好的解。
当达到算法中的某一步不能再继续前进时,算法停止。
背包问题用贪心算法来解决,先求出每件物品的平均价值即p[i]/s[i],然后每次选择利润p[i]/s[i]最大的物品装进背包,这样就使得目标函数增加最快,当最后一种物品放不下时,选择一个适当的拆分,使物品装满背包,使得总的价值最大。
2、棋盘覆盖问题:将2^k x 2^k的棋盘,先分成相等的四块子棋盘,其中特殊方格位于四个中的一个,构造剩下没特殊方格三个子棋盘,将他们中的也假一个方格设为特殊方格。
如果是:左上的子棋盘(若不存在特殊方格)则将该子棋盘右下角的那个方格假设为特殊方格右上的子棋盘(若不存在特殊方格)则将该子棋盘左下角的那个方格假设为特殊方格左下的子棋盘(若不存在特殊方格)则将该子棋盘右上角的那个方格假设为特殊方格右下的子棋盘(若不存在特殊方格)则将该子棋盘左上角的那个方格假设为特殊方格当然上面四种,只可能且必定只有三个成立,那三个假设的特殊方格刚好构成一个L型骨架,我们可以给它们作上相同的标记。
棋盘覆盖实习报告
西南交通大学高级编程课程设计报告设计题目:棋盘覆盖问题院(系):信息科学与技术学院年级: 2014级专业班级:计算机科学与技术组号: 21指导教师:***西南交通大学2015年7月小组成员及内容分工棋盘覆盖问题题目要求:在一个2^k×2^k (k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格,且称该棋盘为一个特殊棋盘。
在棋盘覆盖问题中,要用4种不同形态的L型骨牌覆盖给定的特异盘上除特殊方格以外所有方格,且任何2个L型骨牌不得重叠覆盖。
操作说明:可改变k值,可通过鼠标或者坐标两种方式选取特殊方格目录第1章绪论 (1)1.1设计的背景和意义 (1)1.2 设计的主要内容 (1)1.3 报告的主要内容 (1)第2章需求分析 (2)2.1概述 (2)2.2 设计目标 (2)2.3 功能需求 (2)2.3.1功能1 (2)2.3.2功能2 (3)2.4 性能需求 (3)2.5 外部接口需求 (3)2.6 保密性和安全性需求 (3)第3章总体设计 (4)3.1 概述 (4)3.2 软件系统功能结构 (4)3.2.1功能模块1 (5)3.2.2功能模块2 (5)3.3 软件界面设计 (9)3.2.1界面1 (10)3.2.2界面2 (11)3.3 主要数据结构及文件结构 (11)3.3.1数据结构1 (15)3.3.2数据结构2 (16)3.4 与其他软件的接口............................................................................错误!未定义书签。
3.5 开发及使用环境 (16)3.6 开发计划及安排 (17)第4章详细设计 (18)4.1 概述) (18)4.2 模块1.................................................................................................错误!未定义书签。
棋盘覆盖实验报告心得(3篇)
第1篇一、实验背景棋盘覆盖实验是计算机科学中一个经典的算法问题,旨在研究如何用最少数量的棋子覆盖整个棋盘。
这个实验不仅考验了我们对算法和数据结构的理解,还锻炼了我们的逻辑思维和编程能力。
在本实验中,我选择了使用回溯算法来解决棋盘覆盖问题,以下是我在实验过程中的心得体会。
二、实验目的1. 理解棋盘覆盖问题的背景和意义;2. 掌握回溯算法的基本原理和应用;3. 提高编程能力和逻辑思维能力;4. 分析不同算法的优缺点,为实际应用提供参考。
三、实验过程1. 确定问题模型棋盘覆盖问题可以抽象为一个二维数组,其中每个元素代表棋盘上的一个格子。
我们需要使用棋子(如皇后)来覆盖整个棋盘,使得每个格子都被至少一个棋子覆盖。
在本实验中,我们选择使用N皇后问题作为棋盘覆盖问题的子问题。
2. 设计算法为了解决棋盘覆盖问题,我们可以采用回溯算法。
回溯算法的基本思想是从一个解空间中搜索解,当找到一个解时,将其输出;当发现当前解不满足条件时,回溯到上一个状态,尝试其他可能的解。
具体步骤如下:(1)初始化棋盘,将所有格子设为未覆盖状态;(2)从第一行开始,尝试将棋子放置在该行第一个格子;(3)判断放置棋子后是否满足约束条件,如冲突、越界等;(4)如果满足约束条件,将该格子设为已覆盖状态,继续放置下一行棋子;(5)如果当前行已放置完棋子,检查是否覆盖了整个棋盘;(6)如果覆盖了整个棋盘,输出解;否则,回溯到上一个状态,尝试其他可能的解。
3. 编写代码根据上述算法,我使用Python语言实现了棋盘覆盖问题的回溯算法。
在代码中,我定义了一个二维数组来表示棋盘,并实现了放置棋子、检查约束条件、回溯等功能。
4. 实验结果与分析通过实验,我发现以下结论:(1)随着棋盘大小的增加,回溯算法的搜索空间也随之增大,导致算法的运行时间显著增加;(2)在解决N皇后问题时,当棋盘较大时,回溯算法的效率较低;(3)通过优化算法,如剪枝,可以提高算法的效率。
棋盘覆盖问题和快速排序问题
21. Matrix[tr + s - 1][tc + s - 1] = t;22. chessBoard(tr, tc, tr + s - 1, tc + s - 1, s);23. }24.if (dr < tr + s && dc >= tc + s)25. {26. chessBoard(tr, tc + s, dr, dc, s);27. }28.else29. {30. Matrix[tr + s - 1][tc + s] = t;31. chessBoard(tr, tc + s, tr + s - 1, tc + s, s);32. }33.if (dr >= tr + s && dc < tc + s)34. {35. chessBoard(tr + s, tc, dr, dc, s);36. }37.else38. {39. Matrix[tr + s][tc + s - 1] = t;40. chessBoard(tr + s, tc, tr + s, tc + s - 1, s);41. }42.if (dr >= tr + s && dc >= tc + s)43. {44. chessBoard(tr + s, tc + s, dr, dc, s);45. }46.else47. {48. Matrix[tr + s][tc + s] = t;49. chessBoard(tr + s, tc + s, tr + s, tc + s, s);50. }51.}52.53.int main()54.{55.int size, r, c, row, col;56. printf("请输入棋盘的行列号");57. scanf("%d", &size);58. printf("请输入特殊方格的行列号");59. scanf("%d %d", &row, &col);60. chessBoard(0, 0, row, col, size);61.62.for (r = 0; r < size; r++)63. {64.for (c = 0; c < size; c++)65. {66. printf("%2d ", Matrix[r][c]);67. }68. printf("\n");69. }70.71. system("pause");72.73.return 0;74.}//快速排序算法代码1.#include<bits/stdc++.h>ing namespace std;3.int partition(vector<int> &vi, int low, int up)4.{5.int pivot = vi[up];6.int i = low - 1;7.for (int j = low; j < up; j++)8. {9.if (vi[j] <= pivot)10. {11. i++;12. swap(vi[i], vi[j]);13. }14. }15. swap(vi[i + 1], vi[up]);16.return i + 1;17.}18.void quickSort(vector<int> &vi, int low, int up)19.{20.if (low < up)21. {22.int mid = partition(vi, low, up);23. quickSort(vi, low, mid - 1);24. quickSort(vi, mid + 1, up);25. }26.}27.void qSort(vector<int> &vi)28.{29. quickSort(vi, 0, vi.size() - 1);30.}31.32.int main()33.{34.int a[99999];35.int max = 100000, min = 0;36. srand((unsigned)time(NULL));37.for (int i = 0; i < 10000; i++) {38. a[i] = rand() % (int)(max - min + 1) + min;39. }40. vector<int> va(a, a + 9999);41.42. cout << "Before quicksort:\n";43.for (auto x : va)44. cout << x << " ";45. cout << endl;46.47. qSort(va);48.49. cout << "After quicksort:\n";50.for (auto x : va)51. cout << x << " ";52. cout << endl;53. system("pause");54.return 0;55.}四、程序测试//棋盘覆盖算法//快速排序算法//棋盘覆盖算法//快速排序算法随机生成数(N=10K):排序结果:解:=+-=)1()1(4)(O k T k T3/)14)(1()1(44)1()0(41-+=+=∑-=k k k i i k O O O T得:)4()(k O k T =由于覆盖一个kk 22⨯棋盘所需L 型骨牌个数为故算法是在渐进意义下最优的解//快速排序算法快速排序算法是对冒泡排序算法的一种改进,采用分治策略,步骤如下: 1. 选取一个基准元素(pivot )2. 比pivot 小的放到pivot 左边,比pivot 大的放到pivot 右边3. 对pivot 左边的序列和右边的序列分别递归的执行步骤1和步骤2 平均情况下快速排序的时间复杂度是O (n\lgn ),最坏情况是O(n2)。
棋盘覆盖问题
棋盘覆盖问题
有一个经典问题:8*8的棋盘,去掉了左下角和右上角2个格子,请问能否用31块1*2的骨牌覆盖整个棋盘。
这个问题的答案应该人人都知道吧,染色之后一目了然。
那么,有人要问了:如果去掉的是1红1白的格子各一个,结果是怎样的呢?比如下面的这个图:
你可以自己画几个图试一试。
你能证明一定可以覆盖?还是可以给出反例呢?
据说,这个问题刚出来的时候,通过复杂的理论,终于得到了证明。
也就是只要在这个图中去掉一红一白两格,肯定可以被覆盖。
这里,我们将看到一个复杂的问题怎么通过一个简单的方法来证明。
我们接下来不但要证明可以覆盖,而且要给出覆盖的方法。
看到这里你可能会想到了:构造——对了,只要构造了一组解,原问题便解决了。
我们把原来的棋盘按照下图所示的方法剪开:(沿着绿线):
我们就把这个棋盘变成了一个环。
注意到整个环都是红白相间的。
假设我们从图中去掉一个红色格子,再去掉一个白色格子。
我们就得到两条链:每一条链都是红色->白色->红色...->白色。
这样我们只要沿着链每次的两个格子放即可(注意到相连的两个格子不存在和骨牌形状不同的情况:1*2,你能找出第二种形状吗?)。
把两条链放完,这个棋盘就被覆盖满了,我们的问题也就解决了。
棋盘覆盖问题
分治法棋盘覆盖声明:本文使用的代码和例子的来源:《计算机算法设计与分析》(王晓东编著,电子工业出版社)。
我对代码做了少许修改,使可以在tc的图形模式下看到题目的结果。
题目:在一个(2^k)*(2^k)个方格组成的棋盘上,有一个特殊方格与其他方格不同,称为特殊方格,称这样的棋盘为一个特殊棋盘。
现在要求对棋盘的其余部分用L型方块填满(注:L 型方块由3个单元格组成。
即围棋中比较忌讳的愚形三角,方向随意),切任何两个L型方块不能重叠覆盖。
L型方块的形态如下:■■■■■■■,■ ,■■ ,■■题目的解法使用分治法,即子问题和整体问题具有相同的形式。
我们对棋盘做一个分割,切割一次后的棋盘如图1所示,我们可以看到棋盘被切成4个一样大小的子棋盘,特殊方块必定位于四个子棋盘中的一个。
假设如图1所示,特殊方格位于右上角,我们把一个L型方块(灰色填充)放到图中位置。
这样对于每个子棋盘又各有一个“特殊方块”,我们对每个子棋盘继续这样分割,知道子棋盘的大小为1为止。
用到的L型方块需要(4^k-1)/3 个,算法的时间是O(4^k),是渐进最优解法。
本题目的C语言的完整代码如下(TC2.0下调试),运行时,先输入k的大小,(1<=k< =6),然后分别输入特殊方格所在的位置(x,y), 0<=x,y<=(2^k-1)。
程序将绘制出覆盖后的棋盘,运行效果截图如图2所示。
[此程序在TC下课成功运行。
VC下缺少头文件<graphics.h>,编译时会出现错误。
]#include <stdio.h>#include <graphics.h>/*#include <cpyscr.h>*/#define N 64#define BoardLeft 2#define BoardTop 2int Board[N][N]; /*棋盘*/int tile;/*全局性质的L图形编号*/int CellSize=10;/*网格大小*/int BorderColor=LIGHTGRAY;/*用指定颜色填充一个单元格!*/void PutCell(int x,int y,int color){setfillstyle(SOLID_FILL,color);rectangle(BoardLeft+x*CellSize,BoardTop+y*CellSize,BoardLeft+(x+1) *CellSize,BoardTop+(y+1)*CellSize);floodfill(BoardLeft+x*CellSize+CellSize/2,BoardTop+y*CellSize+Cel lSize/2,BorderColor);}/*绘制L方块,(cx,cy)是L方块的中心点CELL坐标,pos从1到4,表示位于特殊方块位于哪个角(即缺失的一角位置)*/void PutBlock(int cx,int cy,int pos){int x,y,t=CellSize;/*方块起始点像素坐标*/x=BoardLeft+cx*CellSize;y=BoardTop+cy*CellSize;moveto(x,y);/*移动到中心点*/switch(pos){case 1:/*左上角缺*/lineto(x,y-t);lineto(x+t,y-t);lineto(x+t,y+t);lineto(x-t,y+t);lineto(x-t,y);break;case 2:/*右上角缺*/lineto(x+t,y);lineto(x+t,y+t);lineto(x-t,y+t);lineto(x-t,y-t);lineto(x,y-t);break;case 3:/*左下角缺*/lineto(x-t,y);lineto(x-t,y-t);lineto(x+t,y-t);lineto(x+t,y+t);lineto(x,y+t);break;case 4:/*右下角缺*/lineto(x,y+t);lineto(x-t,y+t);lineto(x-t,y-t);lineto(x+t,y-t);lineto(x+t,y);break;}lineto(x,y);/*回到闭合点!*/}/*初始化图形模式*/void InitGraph(){int gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,"");setcolor(BorderColor);}/*关闭图形模式*/void CloseGraph(){closegraph();}/*打印棋盘*/void PrintBoard(int size){int i,j;clrscr();for(j=0;j<size;j++){for(i=0;i<size;i++){printf("%2d ",Board[i][j]);}printf("\n");}printf("\n--------------------------------\n");printf("size=%d;\n");}/*left,top:方块的左上角坐标,x,y:特殊方块的坐标 size:当前的子棋盘大小*/void ChessBoard(int left,int top,int x,int y,int size){int i,t,s,pos;/*t是方块的编号,s是棋盘的一半尺寸!(size/2),pos表示方块位于哪一角 */if(size==1)return;t=tile++;/*当前L行方块的编号!递增*/s=size/2;/*------------处理左上角----------*/if(x<left+s && y<top+s){ChessBoard(left,top,x,y,s);/*设置位于左上角的标识*/ pos=1;}else{Board[left+s-1][top+s-1]=t; /*不在左上角*/ ChessBoard(left,top,left+s-1,top+s-1,s);}/*------------处理右上角----------*/if(x>=left+s && y<top+s){ChessBoard(left+s,top,x,y,s);pos=2;}else{Board[left+s][top+s-1]=t;/*不在右上角*/ChessBoard(left+s,top,left+s,top+s-1,s);}/*------------处理左下角----------*/if(x<left+s && y>=top+s){ChessBoard(left,top+s,x,y,s);pos=3;}else{Board[left+s-1][top+s]=t;ChessBoard(left,top+s,left+s-1,top+s-1,s);}/*------------处理右下角----------*/if(x>=left+s && y>=top+s){ChessBoard(left+s,top+s,x,y,s);pos=4;}else{Board[left+s][top+s]=t;ChessBoard(left+s,top+s,left+s,top+s,s);}/*画出当前的L方块*/PutBlock(left+s,top+s,pos);}void main(){int size,k,x,y,i,j;printf("please input k=? (k should not more than 6, boardsize=2^k ): \n");scanf("%d",&k);size=1<<k;printf("please input position of the special cell. x=? (not more than %d): \n",size-1);scanf("%d",&x);printf("please input position of the special cell. y=? (not more than %d): \n",size-1);scanf("%d",&y);if(k<0 || k>6 || x<0 || x>(size-1) || y<0 || y>(size-1)){printf("Input invalid!\n");return;}InitGraph();tile=1;Board[x][y]=0;/*绘制特殊方块!*/PutCell(x,y,RED);ChessBoard(0,0,x,y,size);/*CopyScreen("c:\\tc\\temp\\chess.bmp",0,0,400,400);*/getch();CloseGraph();}2.#include"stdio.h"#include<graphics.h>#include<dos.h>#include<math.h>int tile=1;int avg;int basex,basey;void chessboard(int tr,int tc,int dr,int dc,int size)/*加了一个int tc*/{int s,t;if(size==1)return;t=tile++;s=size/2;delay(150000);setfillstyle(7,1);sound(500);delay(1500);sound(400);delay(1500);nosound();bar(dr*avg+basex,dc*avg+basey,(dr+1)*avg+basex,(dc+1)*avg+basey);if((dr*avg+basex)<tr+s*avg&&(dc*avg+basey)<tc+s*avg)chessboard(tr,tc,dr,dc,s);else{setfillstyle(1,t);bar(tr+(s-1)*avg,tc+(s-1)*avg,tr+s*avg,tc+s*avg);chessboard(tr,tc,(tr-basex)/avg+s-1,(tc-basey)/avg+s-1,s);}if((dr*avg+basex)<tr+s*avg&&(dc*avg+basey)>=tc+s*avg)chessboard(tr,tc+s*avg,dr,dc,s);else{setfillstyle(1,t);bar(tr+(s-1)*avg,tc+s*avg,tr+s*avg,tc+(s+1)*avg);/*在这加了一个tr+ s*avg*/chessboard(tr,tc+s*avg,(tr-basex)/avg+s-1,(tc-basey)/avg+s,s); }if((dr*avg+basex)>=tr+s*avg&&(dc*avg+basey)<tc+s*avg)chessboard(tr+s*avg,tc,dr,dc,s);else{setfillstyle(1,t);bar(tr+s*avg,tc+(s-1)*avg,tr+(s-1)*avg,tc+s*avg);chessboard(tr+s*avg,tc,(tr-basex)/avg+s,(tc-basey)/avg+s-1,s); }if((dr*avg+basex)>=tr+s*avg&&(dc*avg+basey)>=tc+s*avg)chessboard(tr+s*avg,tc+s*avg,dr,dc,s);else{setfillstyle(1,t);bar(tr+s*avg,tc+s*avg,tr+(s+1)*avg,tc+(s+1)*avg);chessboard(tr+s*avg,tc+s*avg,(tr-basex)/avg+s,(tc-basey)/avg+s,s);}}main(){int size,k;int dr,dc,tr,tc;int endx,endy;int i;double x,y;int gdriver=DETECT;int gmode=VGA;initgraph(&gdriver,&gmode,"");basex=300,basey=100;endx=basex+320;endy=basey+320;cleardevice();setcolor(12);settextstyle(2,0,8);outtextxy(20,20,"zhoumingjiang\n");/*改成了outtextxy函数~~*/ outtextxy(60,60,"designer:zhoumingjiang 25/10/2002");setbkcolor(BLACK);setcolor(RED);printf("\n\n\n");printf(" please input k: ");scanf("%d",&k);x=2;y=k;size=pow(x,y);avg=320/size;rectangle(basex,basey,endx,endy);for(i=0;i<=size;i++){setlinestyle(1,1,6);line(basex,basey+i*avg,endx,basey+i*avg);line(basex+i*avg,basey,basex+i*avg,endy);}printf(" please input dr,dc: ");scanf("%d,%d",&dc,&dr);tr=basex;tc=basey;chessboard(tr,tc,dr,dc,size);}3.棋盘覆盖(C语言)#include <stdio.h>#include <conio.h>#include <math.h>int title=1;int board[64][64];void chessBoard(int tr,int tc,int dr,int dc,int size) {int s,t;if(size==1) return;t=title++;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);}}void main(){ int dr=0,dc=0,s=1,i=0,j=0;printf("print in the size of chess:\n"); scanf("%d",&s);printf("print in specal point x,y:\n"); scanf("%d%d",&dr,&dc);if(dr<s && dc<s){chessBoard(0,0,dr,dc,s);for(i=0;i<s;i++){for(j=0;j<s;j++){printf("%4d",board[i][j]);}printf("\n");}}elseprintf("the wrong specal point!!\n"); getch();}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
运行结果:
求解思路:
核心思路是使用分治算法递归解决棋盘覆盖问题。
棋盘覆盖问题要用4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
棋盘大小为2k,因此分治算法可以将棋盘分成4个等大的子棋盘。
特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。
我们可以用一个L型骨牌覆盖这3个较小的棋盘的汇合处,如下图所示,这3个子棋盘上的方格就成为该棋盘上的特殊方格,从而将原问题化为4个较小规模的棋盘覆盖问题。
递归的使用这种分割,直至棋盘简化为1x1棋盘,便可以完全覆盖棋盘。