时间限制: 1 Sec 内存限制: 64 MB
题目描述
设有n个选手的循环比赛。其中n=2的m次方。要求每名选手要与其他n-1名选手都赛一次。每名选手至少每天比赛一次,循环赛共进行了n-1天,要求每天没有选手轮空。 输入:m 输出:表格形式的比赛安排表。
输入
第1行:1个整数M(1<=M<=8)
输出
N(N=2^M)-1天的比赛安排表。数据以N*N的矩阵形式输出。每行的两个整数之间用一个空格分开。
样例输入
Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
2
样例输出
1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1
既然它被放在了分治作业中,那么这就是一道分治题= =
问题来了,分治?
“分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。”
------------------copied from baidu
细细一看可以发现,把每个正方形分成四个小正方形,左下角和右上角相同,右下角和左上角相同~
于是,详见代码。
#include<cstdio>
int n,m,a[260][260];
void fz(int l,int x1,int x2,int y1,int y2,int dr)
{
int i,j;
if((dr==2||dr==1)&&l==2)
{
a[x1][y1]=y1;a[x1][y2]=y2;a[x2][y1]=y2;a[x2][y2]=y1;
return;
}
if(dr==3)
{
for(i=x1;i<=x2;i++)
for(j=y1;j<=y2;j++)
a[i][j]=a[i-l][j-l];
return;
}
if(dr==4)
{
for(i=x1;i<=x2;i++)
for(j=y1;j<=y2;j++)
a[i][j]=a[i-l][j+l];
return;
}
fz(l/2,x1,x1+l/2-1,y1,y1+l/2-1,1);
fz(l/2,x1,x1+l/2-1,y1+l/2,y1+l-1,2);
fz(l/2,x1+l/2,x1+l-1,y1,y1+l/2-1,4);
fz(l/2,x1+l/2,x1+l-1,y1+l/2,y1+l-1,3);
}
int main()
{
int i,j;
scanf("%d",&m);
n=1<<m;
fz(n,1,n,1,n,1);
for(i=1;i<=n;i++)
{
for(j=1;j<n;j++)
printf("%d ",a[i][j]);
printf("%d\n",a[i][j]);
}
}
/**************************************************************
Problem: 1151
User: C20172037dza
Language: C++
Result: 正确
Time:1 ms
Memory:1292 kb
****************************************************************/
话说明天就月考了好方啊QAQ
顺便说一下,l==2改为l==1,然后a[x1][y1]=y1应该也可以,没提交过。。
再顺便说一下dr的取值,1左上,2右上,3右下,4左下...
再然后,我讲完了。。。。