算法实验一【循环赛日程表】(分治算法)
1243.循环赛日程表
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
用分治算法生成循环赛日程表(1到2的n次方个人)
输入
一个小于等于7的正整数n
输出
循环赛日程表(1到2的n次方个人)
输入样例
3
输出样例
1 2 3 4 5 6 7 8
2 1 4 3 6 5 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<iostream>
using namespace std;
int n;
int a[10000][10000];
void search(int st,int length);//分治
void filltable(int st,int length);//对角填充 左上填右下 左下填右上
int main()
{
int i,j,length;
cin>>n;
length=1;
for(i=0;i<n;i++)
{
length*=2;//人的个数
}
for(i=1;i<=length;i++)
{
a[i][1]=i;//行列均从1开始 ,将第一列的数字填完
}
search(1,length);
for(i=1;i<=length;i++)
{
for(j=1;j<=length;j++)
{
cout<<a[i][j];
if(j!=length) cout<<" ";
}
cout<<endl;
}
return 0;
}
void search(int st,int length)//递归调用,将问题全部划分为两个人的小问题进而解决
{
int i,len;
if(length==2)//人数为2时,此时为最小的问题
{
a[st+1][2]=a[st][1];
a[st][2]=a[st+1][1];
}
else
{
len=length/2;
search(st,len);//左上继续分治 直至只剩两个人
search(st+len,len);//左下继续分治直至只剩两个人
filltable(st,length);//填充该函数下的方块
}
}
void filltable(int st,int length)
{
int i,len,j;
len=length/2;
for(i=st;i<st+len;i++)//左上填充右下
{
for(j=1;j<=len;j++)
{
a[i+len][j+len]=a[i][j];
}
}
for(i=st+len;i<st+2*len;i++)//左下填充右上
{
for(j=1;j<=len;j++)
{
a[i-len][j+len]=a[i][j];
}
}
}
10.16日复习算法
filltable函数里面循环条件为关于st的式子,第一次写的时候在第二个循环里面不自觉的把st代成1了,导致输出错误…
注意细节即可