1. 程式人生 > 實用技巧 >【2020.11.28提高組模擬】T1染色(color)

【2020.11.28提高組模擬】T1染色(color)

【2020.11.28提高組模擬】T1染色(color)

題目

題目描述

給定 \(n\),你現在需要給整數 \(1\)\(n\) 進行染色,使得對於所有的 \(1\leq i<j\leq n\),若 \(i - j\) 為質數,則 \(i\)\(j\) 不同色。
求出顏色儘可能少的染色方案。如果有多種方案,輸出任意一種即可。

輸入格式

第一行一個整數 \(n\)

輸出格式

第一行一個整數 \(k\),表示顏色數。
第二行 \(n\) 個整數 \(col_i\)\(1 \leq col_i \leq k\)),表示 \(i\) 的顏色。

資料範圍

對於\(30\%\)的資料,\(n \leq 10\)


對於 \(60\%\) 的資料,\(n \leq 20\)
對於 \(100\%\) 的資料,\(n \leq 10^4\)

時空限制

​時間限制:1s
​空間限制:128MB

題解

規律題
\(n <8\)直接暴力
\(n \geq8\)\(col_i=(i-1)\%4+1\)
證明:
質數可以分為\(2\)和奇質數,如果按照奇偶性染色,則可以滿足所有奇質數。但因為2,所以要按照\(mod\ 4\)方法染色
考慮答案是否有可能小於4?考慮\(1,3,6,8\),兩兩之間差都是質數,因此答案不能為3
綜上:\(n <8\)直接暴力,\(n \geq8\)\(col_i=(i-1)\%4+1\)

Code

#include<cstdio>
#include<cstring>
using namespace std;
int n,ans,s[10],ans1[10];
bool bj,p[100],color[10];
bool judge()
{
	for (int i=1;i<=n;++i)
		for (int j=1;j<=n;++j)
			if (p[i-j]&&s[i]==s[j]) return false;
	return true;
}
void dg(int x)
{
	if (x>n)
	{
		if (judge())
		{
			int sum=0;
			for (int i=1;i<=4;++i)
				if (color[i]) ++sum;
			if (sum<ans)
			{
				ans=sum;
				for (int i=1;i<=n;++i)
					ans1[i]=s[i];
			}
		}
		return;
	}
	for (int i=1;i<=4;++i)
	{
		s[x]=i;
		bool bz=color[i];
		color[i]=true;
		dg(x+1);
		color[i]=bz;
		s[x]=0;
	}
}
int main()
{
	freopen("color.in","r",stdin);
	freopen("color.out","w",stdout);
	memset(p,true,sizeof(p));
	for (int i=2;i<=8;++i)
		for (int j=2;j<=8;++j)
			p[i*j]=false;
	p[0]=p[1]=false;
	scanf("%d",&n);
	if (n<8)
	{
		ans=10;
		dg(1);
		printf("%d\n",ans);
		for (int i=1;i<=n;++i)
			printf("%d ",ans1[i]);
	}
	else
	{
		printf("4\n");
		for (int i=1;i<=n;++i)
			printf("%d ",(i-1)%4+1);
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}