Codeforces Round #144 (Div. 1) A. Cycles
http://codeforces.com/problemset/problem/232/A
题意:
给你一个数k,用n个点画出k个长度为3的环,然后输出n的个数以及图的矩阵表示,mat[i][j] = 0表示无边 1表示有边。
思路:
如果存在n点的话,则最多能够组合出的长度为3的环有c(n,3)个,当然这些特定的数,不能把k,全部表示出来,我们首先找出C(i,3)<=k的最大的i,然后不断往里面添加点,当我们添加一个点之后,我们可以从已有的图形里面的i个点里面选出2两个与刚加入的节点构成三元环,就这样枚举直到满足k个。
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> #include <string> #define CL(a,num) memset((a),(num),sizeof(a)) #define iabs(x) ((x) > 0 ? (x) : -(x)) #define Min(a,b) (a) > (b)? (b):(a) #define Max(a,b) (a) > (b)? (a):(b) #define ll long long #define inf 0x7f7f7f7f #define MOD 1073741824 #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define test puts("<------------------->") #define maxn 100007 #define M 1000007 #define N 107 using namespace std; //freopen("data.in","r",stdin); int mat[N][N]; int main(){ int k,i,j,ki; while (~scanf("%d",&k)){ CL(mat,0); //首先找出小于等于k的最多的节点数i for (i = 3; i <= 100; ++i){ if (i*(i - 1)*(i - 2)/6 > k) break; } i--; k = k - i*(i - 1)*(i -2)/6; //更新临界矩阵 for (j = 1; j <= i; ++j){ for (ki = 1; ki <= i; ++ki){ mat[j][ki] = (j != ki)*1; } } //printf(">>>%d %d\n",i,k); //逐渐加边,枚举增加的三元环 while (k > 0){ for (j = 2; j <= i; ++j){ if (j*(j - 1)/2 > k) break; } j--; i++;//i++是新加入的节点 for (ki = 1; ki <= j; ++ki) mat[i][ki] = mat[ki][i] = 1; k -= (j*(j - 1)/2); } k = i; printf("%d\n",k); for (i = 1; i <=k ; ++i){ for (j = 1; j <= k; ++j) printf("%d",mat[i][j]); printf("\n"); } } return 0; }