分治法,分开治理的方法。

把问题分开后用什么手段呢?就是程序员最爱的,计算机最恨的----------递归。

1.先来简单说一下题目:

8个运动员进行“地表最强16人”循环赛,日程满足:

·每个选手必须与其他n-1个选手比赛一次;

·每个选手一天只能赛一次;

·循环赛一共进行n-1天;

2.从简到难来看;

从2*2来看;

 

从4*4来看;

 

 总结来看,就是复制,左上和右下互相复制,右上和左下互相复制。

why?  为什么一定要把左边2列分成2*2呢?  往下看!

3.怎么解决这个8*8的问题(大概思路),我们画图解决

如图,左边第一纵列是组员名称,真正要进入递归的部分,是我灰色框起来的部分。

那么,问题来了,递归就是把相同的问题逐渐简单缩小化。

那么在这8*8的格子中,有多少个问题是相等的呢?

首先,我们先分成4个4*4的方格来看;

 

 图2

问题就像我分的颜色一样,这四个格子,左上和左下是最原始的两个问题;

原因很简单,他们的第一列是有数字的!所以,上述问题,虽然他不是左边一列有数字的问题,但是我们可以看成左边第一列有数字。

当左上和左下这两个分好之后,就可以开始按照这个思路继续往里面进行递归了。

 

 

 

 

4.代码

到这里,基本递归的思路就清楚了,所以这个题比较麻烦的是复制,左上复制到右下,左下复制到左上。

你需要找目标点和原始点两个数组对的规律,同时需要限制x和y坐标的范围,让x和y在你需要的空间进行移动。

因此,两个for循环中的限制条件要仔细思考的。

代码如下:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 void scheduled(int arr[8][8], int x, int y, int n)
 5 {
 6     if (n == 1)
 7         return;
 8 
 9     scheduled(arr, x, y, n / 2);//左上
10     scheduled(arr, x + (n / 2), y, n / 2);//左下
11 
12     //赋值
13     //左上到左下
14     int s = n / 2;
15 
16     for (int a = x; a < x + s; a++)
17     {
18         for (int b = y; b < y + s; b++)
19         {
20             arr[a + s][b + s] = arr[a][b];
21         }
22     }
23 
24     //从左下到右上
25     for (int a = x + s; a < x + n; a++)
26     {
27         for (int b = y; b < y + s; b++)
28         {
29             arr[a - s][b + s] = arr[a][b];
30         }
31     }
32 }
33 
34 int main()
35 {
36     int a[8][8];
37     cout << "Please input names of those teams:"<<"\n";
38     for (int x = 0; x < 8; x++)
39         cin >> a[x][0];
40     scheduled(a, 0, 0, 8);
41     cout << "The arrangement is:" << "\n";
42     for (int x = 0; x < 8; x++)
43     {
44         for (int y = 0; y < 8; y++)
45         {
46             cout << a[x][y] << " ";
47         }
48         cout << "\n";
49     }
50 }
posted on 2021-10-14 16:08  甄曲家封的封  阅读(154)  评论(0)    收藏  举报