鸡爪

题目链接

  • 考场上被这道题卡了三个半小时,没想到自己的构造水平这么差……
  • 正解是,考虑“字典序最小”的要求还是有点抽象了,其必要条件是: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;
}
posted @ 2024-07-24 13:33  D06  阅读(5)  评论(0编辑  收藏  举报