题目链接:传送门
题意描述:
John Doe开始思考图论。他思考k (1 ≤ k ≤ 1e5)个环的图是什么样子的,这里的环是由不同的三个点组成的循环图表示为一个环。但他画不出这样的图,他想让你解决这个问题。注意点的个数不超过100.
题目分析:
这道题的解法是贪心。首先,由n(n>=3)个点组成的完全图中环的个数为C(3, n),先算出3到100的完全图的贡献,然后找出刚好小于等于k的贡献。如果我们再全部建新的点一直减去C(3,n)的话,就会超过100个点,所以我们要在旧点的基础上建里新的点,这样子的建点,一个新点与m旧点相连的话,贡献为(m-1)(m-2)/2.然后不断的循环,直至k减为0.得到的图就是答案了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int num[104], n;
vector<int>Q;
int m[105][105];
int main(){
for(int i=3;i<=100;++i){
int temp = i*(i-1)*(i-2)/6;
num[i] = temp;
// cout << num[i] << endl;
}
while(cin >> n){
Q.clear();
int d = n;
int ans = 100;
while(d < num[ans]) ans--;
for(int i=1;i<=ans;++i){
for(int j=1;j<=ans;++j){
if(i != j){
m[i][j] = m[j][i] = 1;
}
}
}
d -= num[ans];
int t = ans-2;
for(int i=t;i>=1;--i){
while(d >= i*(1+i)/2){
d -= i*(1+i)/2;
ans++;
for(int j=1;j<=i+1;++j){
m[ans][j] = m[j][ans] = 1;
}
}
}
cout << ans << endl;
for(int i=1;i<=ans;++i){
for(int j=1;j<=ans;++j){
printf("%d", m[i][j]);
}
printf("\n");
}
}
return 0;
}