https://vjudge.net/problem/CodeForces-1332B
题目大意:给
n
n
n个数,保证
4
<
=
a
i
<
=
1000
4<=a_i<=1000
4<=ai<=1000,且每个数都不是质数。你需要给这些数染色,保证每个数仅被染色一次,且如果两个数被染成了相同的颜色,那么必须保证它们的
g
c
d
>
1
gcd>1
gcd>1。你需要输出使用的颜色总数
m
m
m和染色方案,必须保证
1
<
=
c
o
l
o
r
[
i
]
<
=
m
1<=color[i]<=m
1<=color[i]<=m且
1
<
=
m
<
=
11
1<=m<=11
1<=m<=11,每种颜色至少出现
1
1
1次。
思路:巨水,居然卡了半天,绝了。首先打表出前
11
11
11个质数,因为
a
i
a_i
ai都是在
1000
1000
1000之内的合数,而第
11
11
11个质数
31
∗
31
=
962
31*31=962
31∗31=962,第
12
12
12个质数
37
∗
37
=
1369
37*37=1369
37∗37=1369,所以每个合数都能在这前
11
11
11个质数中找到约数,那么就很简单了,对每个数暴力
c
h
e
c
k
check
check,如果
b
[
j
]
b[j]
b[j]整除
a
[
i
]
a[i]
a[i],就把这个数染成
j
j
j。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1005;
int t,n;
int ans[maxn],b[15],cnt[40];
bool prime(int n)
{
for(int i=2;i*i<=n;i++)
if(n%i==0)
return 0;
return 1;
}
int main()
{
int len=2;
b[1]=2,b[2]=3;
for(int i=4;len<11;i++)
if(prime(i))
b[++len]=i;
scanf("%d",&t);
while(t--)
{
memset(cnt,0,sizeof(cnt));
scanf("%d",&n);
int v,num=0;
for(int i=0;i<n;i++)
{
scanf("%d",&v);
for(int j=1;j<=len;j++)
{
if(v%b[j]==0)
{
if(!cnt[b[j]])
cnt[b[j]]=++num;
ans[i]=cnt[b[j]];
break;
}
}
}
printf("%d\n",num);
for(int i=0;i<n;i++)
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}