概要
分治法求解问题的过程是,将整个问题分解成若干个小问题分而治之。分治法求解很自然可以用一个递归过程来表示。分治法就是一种找大规模问题与小规模问题关系的方法,这恰好也是递归设计方法的一种具体的策略。折半查找也是分治的一种。
例1 残缺棋盘
问题描述:
残缺棋盘是由一个2的k次方*2的k次(k>=1)个方格组成的棋盘,其中恰有1个方格残缺。
上图给出k=1时各种情况的残缺棋盘。这种棋盘叫做3格板,残缺棋盘的问题就是要使用4种三格棋盘覆盖更大的残缺棋盘。在此覆盖中要求:
①两个三格板不能重叠
②三格板不能覆盖残缺方格。
参考代码:
#include <iostream>
using namespace std;
int amount;
char Board[100][100];
void Cover(int tr,int tc,int dr,int dc,int size)
{
int s,t;
if(size<2)
return ;
amount++;
t=amount;
if(t>26){
t=t%26;
}
s=size/2;
if(dr<tr+s&&dc<tc+s)//残缺在左上角
{
//覆盖中间位置
Board[tr+s-1][tc+s]=char(t+'a');//char(t+'a')表示字母,
//这行代码是在char数组的特定位置写入字母。
Board[tr+s][tc+s-1]=char(t+'a');
Board[tr+s][tc+s]=char(t+'a');
Cover(tr,tc,dr,dc,s);//覆盖左上
Cover(tr,tc+s,tr+s-1,tc+s,s);//覆盖右上
Cover(tr+s,tc,tr+s,tc+s-1,s);//覆盖左下
Cover(tr+s,tc+s,tr+s,tc+s,s);//覆盖右下
}
else if(dr<tr+s&&dc>=tc+s)//残缺在右上角
{
Board[tr+s-1][tc+s-1]=char(t+'a');
Board[tr+s][tc+s-1]=char(t+'a');
Board[tr+s][tc+s]=char(t+'a');
Cover(tr,tc,tr+s-1,tc+s-1,s);
Cover(tr,tc+s,dr,dc,s);
Cover(tr+s,tc,tr+s,tc+s-1,s);
Cover(tr+s,tc+s,tr+s,tc+s,s);
}
else if(dr>=tr+s&&dc<tc+s)//残缺在左下
{
Board[tr+s-1][tc+s-1]=char(t+'a');
Board[tr+s-1][tc+s]=char(t+'a');
Board[tr+s][tc+s]=char(t+'a');
Cover(tr,tc,tr+s-1,tc+s-1,s);
Cover(tr,tc+s,tr+s-1,tc+s,s);
Cover(tr+s,tc,dr,dc,s);
Cover(tr+s,tc+s,tr+s,tc+s,s);
}
else
{
Board[tr+s-1][tc+s-1]=char(t+'a');
Board[tr+s-1][tc+s]=char(t+'a');
Board[tr+s][tc+s-1]=char(t+'a');
Cover(tr,tc,tr+s-1,tc+s-1,s);
Cover(tr,tc+s,tr+s-1,tc+s,s);
Cover(tr+s,tc,tr+s,tc+s-1,s);
Cover(tr+s,tc+s,dr,dc,s);
}
}
void Print(int s)
{
for(int i=1;i<=s;i++)
{
for(int j=1;j<=s;j++)
cout<<"----";
cout<<endl;
for(int j=1;j<=s;j++)
cout<<"| "<<Board[i][j]<<" ";
cout<<"|";
cout<<endl;
}
for(int j=1;j<=s;j++)
cout<<"----";
}
int main()
{
int s=1,k,x,y;
cout<<"输入2残缺棋盘的规模:2^k,k=";
cin>>k;
for(int i=1;i<=k;i++)
s*=2;
cout<<"输入棋盘残缺位置(x,y):";
cin>>x>>y;
Board[x][y]=' ';
Cover(1,1,x,y,s);
Print(s);
return 0;
}
附上传送门:https://blog.youkuaiyun.com/gzj_1101/article/details/49368143