考场上脑补了好多种姿势,都不太对,不过确实当时状态太差了,没睡好脑袋很沉,一直都有划水的想法,根本不想去想题,然而还是要想,就并想不出来。估计艹过去的姿势很多,不过题解的那种我并不太会证明,题解是先选一个满矩阵,点数为n,c(n,4)<=k,n从4到70中选,然后再开5个互不相连的点,去连满矩阵里的点,一个点连r个,就多c(r,3)个,70^4枚举前4个,然后二分一蛤找第5个。本来我是71上限选4个,然而这样WA,84%,前面的我都手测过没问题,可能后面有些点达不到,不过70,枚举5个就过了70^4log(70),看似很大,不过我们枚举规定一个顺序,前面的点多,后面的点不超过前面的,常数就小很多,11ms就跑过去了。。。
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#define maxl 76
using namespace std;
int n,k;
bool vis[maxl][maxl];
inline int c3(int r)
{
if(r<3)
return 0;
return r*(r-1)*(r-2)/6;
}
inline int c4(int r)
{
if(r<4)
return 0;
return r*(r-1)*(r-2)*(r-3)/24;
}
inline void prework()
{
n=0;
for(int i=4;i<=70;i++)
if(c4(i)<=k && c4(i+1)>k)
{
n=i;
break;
}
if(n==0)
n=70;
}
inline void solve(int d1,int d2,int d3,int d4,int d5)
{
for(int i=1;i<=d1;i++)
vis[n+1][i]=true,vis[i][n+1]=true;
for(int i=1;i<=d2;i++)
vis[n+2][i]=true,vis[i][n+2]=true;
for(int i=1;i<=d3;i++)
vis[n+3][i]=true,vis[i][n+3]=true;
for(int i=1;i<=d4;i++)
vis[n+4][i]=true,vis[i][n+4]=true;
for(int i=1;i<=d5;i++)
vis[n+5][i]=true,vis[i][n+5]=true;
}
inline int find(int d5)
{
int l=0,r=n,mid;
while(l+1<r)
{
mid=(l+r)>>1;
if(c3(mid)<d5)
l=mid;
else
r=mid;
}
if(c3(l)==d5)
return l;
else
if(c3(l+1)==d5)
return l+1;
else
return 0;
}
inline void mainwork()
{
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
vis[i][j]=true,vis[j][i]=true;
int sum,h;
for(int i=0;i<=n;i++)
for(int j=0;j<=i;j++)
for(int l=0;l<=j;l++)
for(int t=0;t<=l;t++)
{
sum=c4(n)+c3(i)+c3(j)+c3(l)+c3(t);
h=find(k-sum);
if(sum+c3(h)==k)
{
solve(i,j,l,t,h);
return;
}
}
}
inline void print()
{
int m=0;n+=5;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(vis[i][j])
m++;
printf("%d %d\n",n,m);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(vis[i][j])
printf("%d %d\n",i,j);
int cnt=0;
/* for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
for(int l=j+1;l<=n;l++)
for(int t=l+1;t<=n;t++)
if(vis[i][j] && vis[i][l] && vis[i][t]
&&vis[j][l] && vis[j][t] && vis[l][t])
cnt++;
printf("%d\n",cnt);*/
}
int main()
{
srand(time(0));
while(~scanf("%d",&k))
{
prework();
mainwork();
print();
}
return 0;
}