分治法,分开治理的方法。
把问题分开后用什么手段呢?就是程序员最爱的,计算机最恨的----------递归。
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 }
浙公网安备 33010602011771号