C. Practice
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.
题意:
N个人分成两队进行比赛,要求最终任意两个人均参与过一场比赛,且在不同队伍,
每只队伍至少一人。
思路:
很容易想到一半一半的交换,但怎么实现,递归很容易就实现了,脑子短路,
比赛中不知为毛抛弃这个想法,换了一个每次取下标为偶数的数安排到一队。
结果成了较复杂的模拟。
之前写模拟的时候,难确定的是比赛场数,实际上比赛场数就等于
,
巧妙方法将N个人转为二进制(要1~N,不能0~n-1,不然第一人和最后一人不能匹配),
不足K位的补全,每一位共N个0或者1,为0的一队,为1的一队即可。这个规律怎么考虑
的,不是很清楚。。。
二进制代码:
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdio>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
const int M=4e4+100;
vector<int>vc[N];
int main() {
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n,cnt=0;
while(cin>>n) {
cnt=0;
for(int i=0; i<=n; i++)vc[i].clear();
while( (1<<cnt)<n ) {
cnt++;
}
for(int i=0; i<cnt; i++) {
for(int j=1; j<=n; j++) {
if(j>>i&1) {
vc[i].push_back(j);
}
}
}
cout<<cnt<<endl;
for(int i=0; i<cnt; i++) {
cout<<vc[i].size()<<" ";
for(int j=0; j<vc[i].size(); j++) {
cout<<vc[i][j]<<" ";
}
cout<<endl;
}
}
return 0;
}
递归代码实现:
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdio>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
const int M=4e4+100;
vector<int>vc[N];
int dfs(int l,int r,int step) {
if(l==r)return 0;
int mid=(l+r)/2;
for(int i=l; i<=mid; i++) {
vc[step].push_back(i);
}
return max(dfs(l,mid,step+1),dfs(mid+1,r,step+1))+1;
}
int main() {
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n;
while(cin>>n) {
for(int i=0; i<=n; i++)vc[i].clear();
int ans=dfs(1,n,1);
cout<<ans<<endl;
for(int i=1; i<=ans; i++) {
cout<<vc[i].size()<<" ";
for(int j=0; j<vc[i].size(); j++) {
cout<<vc[i][j]<<" ";
}
cout<<endl;
}
}
return 0;
}
大模拟代码实现:
(比赛次数计算可优化),但本身这个代码就很垃圾。。。
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdio>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
const int M=4e4+100;
int arr[N],tmp[N],vis[N];
int main() {
freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
int n;
while(cin>>n) {
memset(vis,0,sizeof(vis));
memset(arr,0,sizeof(arr));
memset(tmp,0,sizeof(tmp));
int tmpn=n;
int num=0,ww=0;
if(n&1) {
tmpn+=1;
}
for(int i=1; i<=tmpn; i++) {
arr[i]=i;
}
while(1) {
int kk=0;
num++;
for(int j=1; j<=tmpn; j+=2) {
tmp[++kk]=arr[j];
//cout<<arr[j]<<"..."<<endl;
if(vis[arr[j+1]]==0) {
ww++;
vis[arr[j+1]]=1;
//cout<<ww<<endl;
if(ww==tmpn-1) {
break;
}
}
tmp[kk+tmpn/2]=arr[j+1];
}
if(ww==tmpn-1)break;
for(int j=1; j<=tmpn; j++) {
arr[j]=tmp[j];
}
}
//cout<<".."<<endl;
if(n%2==0) {
cout<<num<<endl;
for(int i=1; i<=n; i++) {
arr[i]=i;
}
for(int i=1; i<=num; i++) {
cout<<n/2<<" ";
int kk=0;
for(int j=1; j<=n; j+=2) {
cout<<arr[j]<<" ";
tmp[++kk]=arr[j];
tmp[kk+n/2]=arr[j+1];
}
cout<<endl;
for(int j=1; j<=n; j++) {
arr[j]=tmp[j];
}
}
} else {
cout<<num<<endl;
for(int i=1; i<=n; i++) {
arr[i]=i;
}
for(int i=1; i<=num; i++) {
cout<<n/2+1<<" ";
int kk=0;
for(int j=1; j<=n; j+=2) {
cout<<arr[j]<<" ";
tmp[++kk]=arr[j];
tmp[kk+n/2+1]=arr[j+1];
}
cout<<endl;
for(int j=1; j<=n; j++) {
arr[j]=tmp[j];
}
}
}
}
return 0;
}
THE END;