您的位置:首页 > 编程语言 > C语言/C++

棋盘覆盖问题、半数集问题算法解析-C语言

2015-12-10 20:35 323 查看
问题一:棋盘覆盖问题

对于一个规模为的棋盘,其中有一个方格和其他方格完全不同,称这一方格为特殊方格,且称该棋盘为特殊棋盘,设计一种算法可以使用4种不同的L型骨牌来填充棋牌。

解答:采用分治策略。

第一步:把解决规模为K的棋盘问题分为解决4个规模为K-1的子棋盘问题。若K=1,则返回。

第二步:对于含有特殊方格子棋盘返回第一步。

第三步:将其余子棋盘靠近父棋盘中心的方格设为特殊棋盘,且给予这3个棋盘的特殊方格一个唯一的骨牌号,并返回第一步。

具体算法实现:(基于C语言,VC6.0)

void chessboard(int tr,int tc,int dr,int dc,int size)//tr行号 tc列号

{ int t=tile++,s=size/2;//L棋牌号

if(size==1) return;

//覆盖左上角子棋盘

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);

}

}

程序运行图(骨牌号定义为静态变量,因此与本函数调用的次数一致)



问题二:半数集问题,给定一个自然数N,可以产生半数集set(n),如下

(1)n属于半数集。

(2)在n的左边加上一个自然数,但该自然数不能超过最近添加的数的一半

(3)按此规则处理,直到不能添加半数集为终止。

解答:采用分治策略:

对于求解半数集n的问题,可以分解为求解半数集含n/2和不含n/2的半数集,若n为偶数,对于不含n/2的半数集个数有set(n-2)个,对于含n/2的半数集个数有set(n/2)个。

具体公式如下:

具体算法实现:(基于C语言,VC6.0)

int set(int n)

{ int s;

if(n==1) return 1;

if(n==2) return 2;

//若为偶数

if(n%2==0)

s=set(n-2)+set(n/2);

else //若为奇数

s=set(n-1);

return s;

}

程序运行图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: