【Problem description】
设有n个选手进行循环比赛,其中n = 2m,要求每名选手要与其他n-1名选手都赛一次,每名选手每天比赛一次,循环赛共进行n - 1天,要求每天没有选手轮空。
【Input format】
一个正整数m(2 <= m <= 6)。
【Output format】
样例形式的比赛安排表。
【Algorithm design】
模拟
【Problem analysis】
模拟:
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
题目样例暴露了规律:每2^i行的下一行就要针对上一行进行长度为2^i单位之间的调换,直接进行O(mn^2)的模拟就可以过。
【Source code】
#include <bits/stdc++.h>
using namespace std;
int m,num[1001];
int check(int x)
{
int mi=0;
while(x)
{
if((x&1))return mi;
x/=2;
mi++;
}
return mi;
}
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
cin>>m;
for(int i=1;i<=(1<<m);i++)
{
num[i]=i;
cout<<i<<" ";
}//储存第一行
cout<<endl;
for(int i=2;i<=(1<<m);i++)
{
int last=check(i-1);//找到上一行作为2^i的倍数,i的最大值
for(int j=0;j<=last;j++)
for(int k=1;k<=(1<<m);k+=(1<<j+1))
for(int f=1;f<=(1<<j);f++)
swap(num[k+f-1],num[k+f-1+(1<<j)]);//单位格之间进行调换
for(int j=1;j<=(1<<m);j++)
cout<<num[j]<<" ";
cout<<endl;
}
return 0;
}
原文地址:https://www.cnblogs.com/qswx/p/9411313.html