Composite Coloring
题意
给定一堆合数,要对合数进行染色,要求不互质的两个数可以用同一种颜色,所用颜色不能超过11种。
对于每一组数据,输出一种染色方案,不要求以最少或最多的颜色。
思路
平方小于1000的质数总共有这11个:2,3,5,7,11,13,17,19,23,29,31。
一个合数的最小质因子一定小于该合数的根号,那么1000以内的数的因子里都或多或少包含着这一个或几个质数。
以质数作最底层的因子,对每一个用到的质数染色,每个合数与它最小的质因子同色。
当然,题目之所以说不超过11种就能解决,也是对应这11个质数。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int t;
int n;
int m;//质数个数
int prime[1005];
int v[1005];
int c[1005];
int color;
int ans[1005];
void primes(int n)
{
for(int i = 2; i <= n; ++i){
if(v[i])
continue;
prime[++m] = i;
for(int j = i; j <= n/i; ++j)
v[i*j] = 1;
}
}
int main()
{
primes(1000);//筛1000以内质数(实际用不了这么多)
cin >> t;
while(t--){
color = 0;
memset(ans,0,sizeof ans);
memset(c,0,sizeof c);
cin >> n;
for(int i = 1; i <= n; ++i){
int x;
cin >> x;
for(int j = 1; j <= m; ++j){//遍历质数
if(x%prime[j]==0){
if(!c[prime[j]])//给没有颜色的素材染上颜色
c[prime[j]] = ++color;
ans[i] = c[prime[j]];//记录每个合数的颜色
break;
}
}
}
printf("%d\n",color);
for(int i = 1; i <= n; ++i)
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}