题目链接:http://codeforces.com/problemset/problem/234/G
题意:问有n个球员,至少安排多少场练习赛,才能让所有球员之间都处于过不同的队伍。并输出每次练习赛第一队人数及球员序号。
思路:假设有7个人,1,2,3,4,5,6,7;递归二分这个序列直到剩一个序号为止,记录每次二分左边的序号,
第一次:1,2, 3,/4 5 6 7 第一队: 1 2 3
第二次:1 / 2 3 /4 5 / 6 7 第一队: 1 4 5
第三次:1 /2 /3 / 4 / 5 / 6 / 7 第一队: 2,4,6
一开始想到二分了但是不知道用递归的话怎么把每次第一队的序号输出,看了下题解才明白可以把递归增加一个x代表递归次数,在把序号存储到相应的数组中就好了
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
int d[20][1000];
int num[20];
void solve(int l,int r,int x){
if(l>=r) return;
int mid=(l+r-1)/2;
// printf("mid=%d\n",mid);
// num[x]+=mid-l+1;
int t=0;
for(int i=l;i<=mid;i++){
d[x][num[x]++]=i;
}
solve(l,mid,x+1);
solve(mid+1,r,x+1);
}
int main(){
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
memset(num,0,sizeof(num));
int n;
scanf("%d",&n);
int ans=0;
while(1<<ans<n) ans++;
printf("%d\n",ans);
solve(1,n,1);
for(int i=1;i<=ans;i++){
printf("%d ",num[i]);
for(int j=0;j<num[i];j++){
printf("%d ",d[i][j]);
}
printf("\n");
}
return 0;
}