题目链接
- 考场上被这道题卡了三个半小时,没想到自己的构造水平这么差……
- 正解是,考虑“字典序最小”的要求还是有点抽象了,其必要条件是:1号点连的边尽量多,相同时2号点连的边尽量多,相同时3号点连的边尽量多,以此类推
- 构造题的核心在于数学推导而不在于代码实现
- 一步步优化得到正解似乎是可行的,但耗时太长;这次你推导3个多小时,迭代到第八个版本才通过;所以,下次做构造题遇到瓶颈时,不妨先去看一下别的题目,一段时间后再重新审视这道题,或许会有不一样的发现
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
if(n/3>=4)
{
for(int i=1;i<=n/3+2;i++)
{
printf("1 %d\n",i+1);
}
for(int i=1;i<=n%3;i++)
{
printf("1 %d\n",n/3+3+i);
}
for(int i=1;i<=n/3;i++)
{
printf("2 %d\n",i+2);
}
for(int i=1;i<=n/3-2;i++)
{
printf("3 %d\n",3+i);
}
}
else if(n/3>=2)
{
for(int i=1;i<=n/3+2;i++)
{
printf("1 %d\n",i+1);
}
for(int i=1;i<=n%3;i++)
{
printf("1 %d\n",n/3+3+i);
}
if(n/3==2)
{
printf("2 3\n");
printf("2 4\n");
}
else
{
printf("2 3\n");
printf("2 4\n");
printf("2 5\n");
printf("3 4\n");
}
}
else if(n/3>=1)
{
int cnt=n/3+3;
printf("1 2\n");
printf("1 3\n");
printf("1 4\n");
for(int i=1;i<=n%3;i++)
{
printf("1 %d\n",cnt+i);
}
}
else
{
for(int i=1;i<=n;i++)
{
printf("%d %d\n",1,i+1);
}
}
}
return 0;
}