Codeforces Round #630 (Div. 2) B. Composite Coloring (数论)
题意:给n个合数(存在两大于1相乘等于ai的因数)将最大公因数大于1的数分为一组,求每个数在哪个组(m<=11)
思路:ai<=1000,由数论知识可知任意大于1的整数的最小的大于1的因数为素数,又该数为合数,必存在一个小于等于sqrt(ai)的因数,所以该素数在sqrt(1000)内。即求出sqrt(1000)的因数即可,经计算可知小于等于sqrt(1000)的因数刚好11个。正好满足。
#include<bits/stdc++.h>
using namespace std;
int pr[12];
void ss(int n){ //线性筛求素数
int vis[n+1]={};
vis[0]=vis[1]=1;
for(int i=2;i<=sqrt(n);i++)
if(!vis[i])
for(int j=i*i;j<=n;j+=i) vis[j]=1;//printf("j=%d\n",j);
int k=0;
for(int i=2;i<=n;i++)
if(!vis[i]) pr[++k]=i;
}
int main(){
int t,n;
ss(sqrt(1000));
/*for(int i=1;i<=11;i++) cout<<pr[i]<<endl; */
cin>>t;
while(t--){
cin>>n;
int a[n+1],c[n+1]={},cnt=1;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=11;i++)
{ int f=0;
for(int j=1;j<=n;j++)
if(a[j]%pr[i]==0&&!c[j])
c[j]=cnt,f=1;
if(f) cnt++;
}
cout<<cnt-1<<endl;
for(int i=1;i<=n;i++)
printf(i==n?"%d\n":"%d ",c[i]);
}
return 0;
}