Practice(CF-234E)
Problem Description
Little time is left before Berland annual football championship. Therefore the coach of team "Losewille Rangers" decided to resume the practice, that were indefinitely interrupted for uncertain reasons. Overall there are n players in "Losewille Rangers". Each player on the team has a number — a unique integer from 1 to n. To prepare for the championship, the coach Mr. Floppe decided to spend some number of practices.
Mr. Floppe spent some long nights of his holiday planning how to conduct the practices. He came to a very complex practice system. Each practice consists of one game, all n players of the team take part in the game. The players are sorted into two teams in some way. In this case, the teams may have different numbers of players, but each team must have at least one player.
The coach wants to be sure that after the series of the practice sessions each pair of players had at least one practice, when they played in different teams. As the players' energy is limited, the coach wants to achieve the goal in the least number of practices.
Help him to schedule the practices.
Input
A single input line contains integer n (2 ≤ n ≤ 1000).
Output
In the first line print m — the minimum number of practices the coach will have to schedule. Then print the descriptions of the practices in m lines.
In the i-th of those lines print fi — the number of players in the first team during the i-th practice (1 ≤ fi < n), and fi numbers from 1 to n — the numbers of players in the first team. The rest of the players will play in the second team during this practice. Separate numbers on a line with spaces. Print the numbers of the players in any order. If there are multiple optimal solutions, print any of them.
Examples
Input
2
Output
1
1 1Input
3
Output
2
2 1 2
1 1
题意:有 n 个人编号从 1~n,现在要举行若干场比赛,每场比赛划分为两组, 每组人数最少为 1 个,要求经过若干场比赛后,能够使得每个人都与其他人打过比赛,问最少的比赛场次,以及每场比赛第一组的人数和人员安排
思路:
有些类似二分,易得出 n=2^p 是最优的,以 12345678 为例,需要进行三场比赛,每场的安排为:1234 与 5678、5634 与 1278、1674 与 5238
第一场,四个人一队进行比赛
第二场,第一队前两个与第二队前两个交换
第三场,第一队每两个与第二队每两个交换
推广到 n 场,有:第一队每 2^(p-i+1) 个人与第二队对应的人交换
在结构体 Node 中使用两个 vector 分别表示第一队、第二队,然后在 vector 利用 Node,每次加入的表示第 i 次交换的结果
Source Program
#include<bits/stdc++.h>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 1000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
struct Node{
vector<int> first;
vector<int> second;
Node(){}
Node(vector<int> first,vector<int> second):first(first),second(second){}
};
int main(){
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n;
scanf("%d",&n);
// int res=floor(log(10)/log(2));
int tot=0;
while((1<<tot)<=n)
tot++;
vector<Node> V;
for(int i=0;i<tot;i++){
vector<int> first,second;
for(int j=0;j<n;j++){
int pos=j>>i;//对于j来说每i个取一次
if(pos%2)
first.push_back(j);
else
second.push_back(j);
}
if(!first.empty()&&!second.empty())
V.push_back(Node(first,second));
}
printf("%d\n",V.size());
for(int i=0;i<V.size();i++){
int len=V[i].first.size();
printf("%d ",len);
for(int j=0;j<len;j++)
printf("%d ",V[i].first[j]);
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号