翻译: 小L要举办一场派对,他有n个朋友可以邀请来参加。派对会持续若干天,为了保证每个人都能玩得开心,小L希望,对于这若干天中的任意两天,都存在某个人参加了这两天的派对;而为了保证朋友们不会觉得他偏心,对于任意三天,都不存在某个人参加了所有这三天的派对。求小L最多能举办多少天派对。 3 <= n <= 10000
输入格式:一行,一个正整数n。
输入格式:一行,一个正整数n。
输出格式:第一行输出一个整数k,表示派对最多能举行的天数。接下来k行,第i行输出若干个整数,表示在第i天时,小L应该邀请哪些朋友(从1到n编号)。如果有多个方案,输出任意一个。
解:考虑第一行有的下面每一行都要有,每个人只能出现两次。
首先构造出:
1234
1
2
3
4
然后1234就都不能用了。
开始用5再填。
1234
1567
25
36
47
不难发现,填好的矩阵都是这样的,依次向下填。
解出公式ans = [(sqrt(8n-1)-1)/2] + 1
注意前一部分要取整。
#include <bits/stdc++.h>
using namespace std;
int a1[200][200];
int main(){
double n;
scanf("%lf", &n);
double t = ((double)sqrt(8*n+1)-1)/2.0;
int ans = t+1;
printf("%d\n", ans);
int cnt = 0;
for(int i = 1; i <= ans-1; i ++){
for(int j = i; j <= ans-1; j ++){
a1[i][j] = ++cnt;
}
}
cnt = 0;
for(int i = 1; i <= ans-1; i ++){
for(int j = i+1; j <= ans; j ++){
a1[j][i] = ++cnt;
}
}
for(int i = 1; i <= ans; i ++){
for(int j = 1; j <= ans-1; j ++){
printf("%d ", a1[i][j]);
}
printf("\n");
}
return 0;
}