Cycles (贪心)

题目链接:传送门

题意描述:

        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;
}

猜你喜欢

转载自blog.csdn.net/weixin_41100093/article/details/87636268