1.分治算法:将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。
2.算法举例:
(1)快速排序
#include <iostream>
using namespace std;
void fun(int *arr,int start,int end){
if(start<end){
int temp=arr[start];
int s=start,e=end;
while(s!=e){
while(s<e && arr[e]>=temp) e--;
arr[s]=arr[e];
while(s<e && arr[s]<=temp) s++;
arr[e]=arr[s];
}
arr[s]=temp;
fun(arr,start,s-1); //对左半段排序
fun(arr,s+1,end); //对右半段排序
}else {
return ;
}
}
int main(){
int a[9]={4,6,3,2,1,5,8,7,9};
fun(a,0,8);
for(int i=0;i<9;i++){
cout << a[i] << " ";
}
cout << endl;
return 0;
}
(2)快排之快速定位
#include <iostream>
using namespace std;
int fun(int *arr,int start,int end,int k){
if(start<end){
int temp=arr[start];
int s=start,e=end;
while(s!=e){
while(s<e && arr[e]>=temp) e--;
arr[s]=arr[e];
while(s<e && arr[s]<=temp) s++;
arr[e]=arr[s];
}
arr[s]=temp;
if(s==k-1) return arr[s];
if(s>k-1) return fun(arr,start,s-1,k);
if(s<k-1) return fun(arr,s+1,end,k);
}else if(start==end && k-1==start) {
return arr[start];
}
}
int main(){
int a[9]={4,6,3,2,1,5,8,7,9};
int res=fun(a,0,8,5);
cout << res << endl;
return 0;
}
3.棋盘算法
#include <iostream>
using namespace std;
#define N 8 // 棋盘行(列)数
int tile = 1; // 骨牌编号
int Board[N][N];// 棋盘
/* tr : 棋盘左上角的行号;
tc : 棋盘左上角的列号;
dr : 特殊方格左上角的行号;
dc : 特殊方格左上角的列号;
size :size = 2^k 棋盘规格为2^k*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-else同理)
if (dr < tr + s && dc < tc + s)
ChessBoard(tr, tc, dr, dc, s);
// 此棋盘中无特殊方格(下面三个if-else同理)
else
{
Board[tr + s - 1][tc + s - 1] = t; // 用编号为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; // 用编号为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; // 用编号为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; // 用编号为t的骨牌覆盖左上角
ChessBoard(tr + s, tc + s, tr + s, tc + s, s); //覆盖其余方格
}
}
int main()
{
cout << "棋盘覆盖问题,k=" << N/2 << endl;
// 将数组(棋盘)所有元素设为0
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
Board[i][j] = 0;
// 棋盘覆盖
ChessBoard(0, 0, 3, 1, N);
// 打印棋盘覆盖情况
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
cout << Board[i][j] << "\t";
cout << endl;
}
}