【LibreOJ NOIP Round #1】游戏
这题这么简单,过的人居然这么少啊hhh
原题:
注意到一个点数为k的完全图所含3元环数量为c(k,3)
可以设想,是否能构造出一个由若干个独立完全图拼成的图,使得三元环数为n
首先完全图点数k在500范围内,c(k,3)的数量很大,需求的三元环可以由几个大连通块快速满足
而3个点构成的完全图三元环数为1,因此任意数量的三元环都可以用这种方法拼成
所以用独立完全图拼的构造方法是对的,只需从大到小枚举k,只要能把c(k,3)塞进就减少剩余所需数量就行
输出方案的办法有很多,附上的代码应该是比较简单的一种
代码:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 using ll=long long int; 5 int e[510][510],n; 6 int q[510],hd=0; 7 inline ll c3(ll x){ return x*(x-1)*(x-2)/6;} 8 int main(){ 9 scanf("%d",&n); 10 for(int i=500;i>=3 && n>0;--i){ 11 for(;n>=c3(i);n-=c3(i)){ 12 q[++hd]=i; 13 } 14 } 15 for(int k=1;k<=hd;++k){ 16 for(int i=q[k-1]+1;i<=q[k-1]+q[k];++i) 17 for(int j=q[k-1]+1;j<=q[k-1]+q[k];++j) 18 e[i][j]=1; 19 q[k]+=q[k-1]; 20 } 21 printf("%d\n",q[hd]); 22 for(int i=1;i<q[hd];++i){ 23 for(int j=1;i+j<=q[hd];++j){ 24 printf("%d",e[i][i+j]); 25 if(i+j!=q[hd]) printf(" "); 26 } 27 printf("\n"); 28 } 29 return 0; 30 }