【2020.11.28提高组模拟】T1 染色(color) 题解

【2020.11.28提高组模拟】T1 染色(color) 题解

题意描述

给长度为n的数列染色,若\(i-j\)为质数那么\(i,j\)异色。求最小需要的颜色种类并构造出一组。

\(n\le10^4\).

Solution

考虑构造出一组稳定的循环染色方案,数列上一周期的颜色相同。若循环节为\(1,2\)显然不行(因为\(2\)是质数),同理还有\(3\)也不行(因为\(3\)是质数)。而更大的质数都不是\(4\)的倍数,所以循环节最小是\(4\).

所以种类=\(min(n,4)\),构造出的答案就是\(1,2,3,4,1,2,3,4,1,2,3,4,1,\dots\)

注意6及以内要特判或者暴力搞就完事了。

范围里的\(n\le 10^4\)是吓人的,\(jz\)签到题的老传统了。

Code

bool book[100010];
//int prime[100010];
//int size;
int n;
int i,j;
void pre()
{
	book[1]=1;
	for(i=2;i<=n;i++)
	{
		if(!book[i])
		{
//			prime[size++]=i;
			for(j=2;i*j<=n;j++)
			{
				book[i*j]=1;
			}
		}
	}
}
int color;
int a[10010];
bool had[10010];
int main()
{
//	freopen("color.in","r",stdin);
//	freopen("color.out","w",stdout);
	n=read();
	///*
	if(n==7)
	{
		cout<<"4\n1 2 2 3 3 4 1 ";
		return 0;
	}
	
	
	//*/
	if(n>6)
	{
		for(i=1;i<=n;i++) a[i]=(i-1)%4+1,color=max(color,(i-1)%4+1);
		cout<<color<<endl;
		for(i=1;i<=n;i++) cout<<a[i]<<" ";
		return 0;
	}
	pre();
	for(i=1;i<=n;i++)
	{
		memset(had,0,sizeof(had));
		for(j=1;j<i;j++)
		{
			if(!book[i-j]) had[a[j]]=1;
		}
		bool succ=0;
		for(j=1;j<=color&&!succ;j++)
		{
			if(!had[j]) a[i]=j,succ=1;
		}
		if(!succ) a[i]=++color;
	}
	
	cout<<color<<endl;
	for(int i=1;i<=n;i++) cout<<a[i]<<" ";
	return 0;
}
posted @ 2020-11-28 17:49  Vanilla_chan  阅读(125)  评论(0编辑  收藏  举报