好多事情,今晚要上安卓选修了,学多一技防身 = =
题意
第一行给一个k,表示你要构造一些点和他们之间的边,使得所组成的不同的三角形恰好为k个
第一行输出你选了n个点,下面输出n*n的邻接矩阵来表示点和边之间的联系,0位没有建边,1位有建边
注意 3 <= n <= 100,1 <= k <= 1e5
input
1
output
3
011
101
110
input
10
output
5
01111
10111
11011
11101
11110
思路
思路嘛。。当时写写画画没什么思路 = =
思路是先建立一个有n个点的完全图,就是每个点之间都有连边,说明这些点不能再连了。这个n个点形成的完全图有的三角形个数要>=k,说明n-1个点形成的完全图,再添加一些点连边,就能达到k,然后我们要找找添加点和边,产生的三角形的规律 = =
下表n表示n个点,m表示连m条边,sum表示有sum个不同的三角形
n | m | sum |
---|---|---|
3 | 3 | 1 |
4 | 3 + 2 = 5 | 1+1 = 2 |
4 | 5 + 1 = 6 | 2 + 2 = 4 |
5 | 6 + 2 = 8 | 4 + 1 = 5 |
5 | 8 + 1 = 9 | 5 + 2 = 7 |
6 | 8 + 2 = 10 | 5 + 1 = 6 |
可以看出在n-1个点的完全图上,添加第n个点,第一次要连2条边,sum增加1,第二次要连1条边,sum增加2,在写下去就发现第三次要连1条边,sum增加3
所以n个点的完全图,有(1)+(1+2)+(1+2+3)+…+(1+2+…+n-2)个不同的三角形,因为(1)+(1+2)+(1+2+3)+…+(1+2+…+n)= n*(n+1)*(n+2) / 6,
把 n+2 变成n,(1)+(1+2)+(1+2+3)+…+(1+2+…+n-2)= (n-2)*(n-1)*n / 6
最后还有一点,一个新开的点,连边之后,三角形增加的数量是+1,+2,+3… 倘若要增加边数为2,就要再新开一个点,新开的第一个点+1个三角形,新开的第二个点+1个三角形,就能达到2个,昨晚wa了一发 = =
代码
#include <algorithm>// ¨|¨|¨| ¨|¨|¨|¨|
#include <iostream>// ¨}¨}¨}¨} ¨~¨~¨~
#include <cstring>// ¨~¨~ ¨~¨~ ¨~¨~
#include <stdio.h>// ¨~¨~ ¨~¨~ ¨~¨~
#include <vector>// ¨~¨~ ¨~¨~ ¨~¨~
#include <cmath>// ¨~¨~ ¨~¨~ ¨~¨~
#include <queue>// ¨~¨~ ¨~¨~¨~¨~ ¨~¨~
#include <map>// ¨~¨~ ¨~¨~ ¨~¨~
using namespace std ;// ¨~¨~ ¨~¨~ ¨~¨~¨~
typedef long long ll;// ¨~¨~ ¨~¨~ ¨~¨~¨~¨~¨~
#define pi pair<int,int> ///
#define P(x,y) make_pair(x,y)
const int maxn = 1e5 + 5;
const ll mod = 998244353;
ll read()
{
ll x=0;char ch=getchar(); bool flag = false;
if(ch=='-') { flag = true; ch = getchar();}
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
if(flag) return -x; else return x;
}
int ans[105][105];
int main()
{ if(fopen("in.txt","r")) freopen("in.txt","r",stdin);
int T,n,m,k,i,sum,j,t,tmp,t2,k1,k2;
scanf("%d",&k);
for(i=3;i<=100;i++)
if(i*(i-1)*(i-2)/6>=k){
t = i-1;
break;
}
tmp = k - t*(t-1)*(t-2)/6;
// cout<<tmp<<endl;
for(i=1;i<=t;i++)
for(j=1;j<=t;j++)
if(i!=j) ans[i][j] = 1;
if(tmp==0){
printf("%d\n",t);
for(i=1;i<=t;i++){
for(j=1;j<=t;j++) printf("%d",ans[i][j]);
printf("\n");
}
}else{
int cnt = 1;
for(i=t+1;i<=100;i++){
while(tmp>=cnt){
if(cnt==1){
ans[1][i] = ans[2][i] = ans[i][1] = ans[i][2] = 1;
}else{
for(j=3;j<=cnt+1;j++)
ans[j][i] = ans[i][j] = 1;
}
tmp -= cnt;
cnt++;
}
if(tmp!=0&&tmp<cnt) cnt = 1;
else break;
}
t = i;
printf("%d\n",t);
for(i=1;i<=t;i++){
for(j=1;j<=t;j++) printf("%d",ans[i][j]);
printf("\n");
}
}
return 0;
}