分治算法的基本思想是将一个计算复杂的问题分为若干个问题来进行求解,然后综合各个小问题得到复杂问题的最终答案,如果这些字问题还是比较大,难以解决,可以再把他们分成若干个更小的子问题,直到可以直接求出答案为止。
一般具有以下特征的问题可使用分治发来求解:
1 求解问题可以分解成若干个规模较小的相同问题。
2 求解问题的规模分解到一定程度时,就能够很容易的求解。
3 合并子问题的解可以得到求解问题的解。
4 由求解问题所分解出的各个子问题是相互独立的。
问题来了: 某学校举行乒乓球比赛,在初赛阶段设置为循环赛,设有n位选手参加,初赛共进行n-1天举行。每位选手要于其他每一位选手进行一场比赛,然后按照积分排名选拔进入决赛的选手,规定,每位选手每天必须比赛一场 不能轮空。按此要求为比赛安排具体日程。
按照分治算法来简化日程的安排,可以将所有参赛选手分为两半,则n个选手的比赛日程可以通过n/2个选手比赛日程来决定,继续用这种一分为二的方法对选手进行划分,知道剩下2位选手时情况就很简单了。
// 编程算法之分治法.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#define MAXN 64
int a[MAXN+1][MAXN+1] = {0};
void gamecal(int k,int n)
{
int i,j;
if (n==2)
{
a[k][1] = k;
a[k][2] = k+1;
a[k+1][1]=k+1;
a[k+1][2]=k;
}
else
{
gamecal(k,n/2);
gamecal(k+n/2,n/2);
for(i = k;i<k+n/2;++i)
{
for(j = n/2+1;j<=n;++j)
{
a[i][j] = a[i+n/2][j-n/2];
}
}
for(i = k+n/2;i<k+n;++i)
{
for(j = n/2+1;j<=n;++j)
{
a[i][j] = a[i-n/2][j-n/2];
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int m ,i ,j;
printf("请输入参赛选手的数量:");
scanf_s("%d",&m);
j=2;
for(i=2;i<8;i++)
{
j = j*2;
if(j==m) break;
}
if(i>=8)
{
printf("参赛选手必须为2的整数次幂,并且不能超过64\n");
return 0;
}
gamecal(1,m);
printf("\n编号");
for(i=2;i<=m;++i)
{
printf("%2d天",i-1);
}
printf("\n");
for(i = 1;i<=m;++i)
{
for(j=1;i<=m;++i)
printf("%4d",a[i][j]);
printf("\n");
}
system("pause");
return 0;
}