参考博客

循环日程表问题。j天遇到的选手。

该问题和棋盘问题很像,都可以通过递归思想来解。

递归三部曲
划分问题:将1个运动员。
递归求解:递归填充1
合并问题:该问题不需要合并。

将日程表看做是一个1这样的四个子表格,再按照如下方法填充。

递归填充方式
因为1了,且每次填充都将其他子表格的左上子表格左上角预先填充了,所以左上子表格的左上角不需要填充。
填充右下子表格的左上角为左上子表格的左上角值。
填充右上子表格的左上角为左上子表格的左上角值加上子表格当前大小(边长)。
同上条一样,填充左下子表格的左上角。
填充完毕之后,再递归填充1

循环日程表问题(分治递归) 

8填充一次后的日程表
分析:他是由四块拼起来的,左上角是n = 4时的一组解,左下角是左上角每个数加4得到,右上角和右下角分别由左下角和左上角复制得到的。
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 const int Max = 100;
 7 int g[Max][Max];
 8 void circulateSchedule(int row, int col, int n)
 9 {
10     if (n == 1) // 当n== 1时,递归结束
11         return;
12     int half = n / 2;
13     g[row + half][col + half] = g[row][col]; // 右下角 = 左上角
14     g[row + half][col] = g[row][col + half] = g[row][col] + half; //右上角和左下角 都是由左上角加上half
15     circulateSchedule(row, col, half); // 递归左上角
16     circulateSchedule(row, col + half, half); // 右上角
17     circulateSchedule(row + half, col, half);//左下角
18     circulateSchedule(row + half, col + half, half);//右下角
19 }
20 int main()
21 {
22     int n;
23     scanf("%d", &n);
24     g[1][1] = 1; // 初始化左上角第一个
25     circulateSchedule(1, 1, n);
26     for (int i = 1; i <= n; i++)
27     {
28         for (int j = 1; j < n; j++)
29             printf("%d ", g[i][j]);
30         printf("%d\n", g[i][n]);
31     }
32     return 0;
33 }
View Code

相关文章: