Num.4 分治算法
算法思路
使用分治法设计程序时,一般可按以下步骤进行:
- 分解:将要求解的问题划分成若干规模较小的同类问题;
- 求解:当子问题划分的足够小时,用较简单的方法解决;
- 合并:按求解问题的要求,将子问题的解逐层合并,即可构成最终的解。
举例说明:乒乓球比赛赛程
循环日程表(8人),每天每位选手比赛一场,怎样在最短时间内完成比赛?
时间 | 第1天 | 第2天 | 第3天 | 第4天 | 第5天 | 第6天 | 第7天 |
---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
2 | 1 | 4 | 3 | 6 | 6 | 8 | 7 |
3 | 4 | 1 | 2 | 7 | 8 | 5 | 6 |
4 | 3 | 2 | 1 | 8 | 7 | 6 | 5 |
5 | 6 | 7 | 8 | 1 | 2 | 3 | 4 |
6 | 5 | 8 | 7 | 2 | 1 | 4 | 3 |
7 | 8 | 5 | 6 | 3 | 4 | 1 | 2 |
8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
#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 main()
{
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");
getchar();
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; j <= m; j++)
printf("%4d", a[i][j]);
printf("\n");
}
while (getchar() != 'q');
return 0;
}