Codeforces Round #630 (Div. 2) B. Composite Coloring(数论)

明明感觉以前好像写过,但是题目都看了两天。。。

https://codeforces.com/contest/1332/problem/B

题目大意:

给定n个合数(这些数字都在1000以内),给定m范围是【1,11】;

让我们用这11个数字给n染色,每一种颜色里面的数字的gcd都要>1;

注意:我们填充数字的时候,必须要一个一个填充,就是1填完了填2,不能1填完了填3。

不用最大或最小化操作,一直填的去就行了。
input 
3
3
6 10 15
2
4 9
23
437 519 865 808 909 391 194 291 237 395 323 365 511 497 781 737 871 559 731 697 779 841 961
output 
1
1 1 1
2
2 1
11
4 7 8 10 7 3 10 7 7 8 3 1 1 5 5 9 2 2 3 3 4 11 6
  • 唯一分解定理:一个数字能够分解成若干个素数的乘积

  • 题目也很巧妙,刚好11个数字,刚好1000以内的11个素数就可以把所有数分解完

  • 所以我们就只需要合理安排数据的安放排列就行了

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=200200,M=2002;
LL a[N],b[N],flag[N];
LL prime[]={2,3,5,7,11,13,17,19,23,29,31};
//唯一分解定理:一个数字能够分解成若干个素数的乘积
//31*31<=1000
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    cin>>T;
    while(T--)
    {
        memset(flag,0,sizeof flag);
        LL n;
        cin>>n;
        for(LL i=1;i<=n;i++)
            cin>>a[i];
        LL sum=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<11;j++)
            {
                if(a[i]%prime[j]==0)
                {
                    //当前的质数已经被定义过下标,直接使用
                    if(flag[j]!=0) b[i]=flag[j];
					else
                    {
                        //当前的质数未被定义下标,在总数的位置上添加
                        flag[j]=++sum;
                        b[i]=flag[j];
                    }
					break;
                }
            }
        }
        cout<<sum<<endl;
        for(int i=1;i<=n;i++)
		{
		    cout<<b[i]<<" ";
		}
        cout<<endl;
    }
    return 0;
}

posted @ 2022-10-04 00:12  Vijurria  阅读(18)  评论(0编辑  收藏  举报