You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

##AcWing 1293. 夏洛克和他的女朋友

一、题目大意

夏洛克有了一个新女友(这太不像他了!)。

情人节到了,他想送给女友一些珠宝当做礼物。

他买了 n 件珠宝,第 i 件的价值是 i+1,也就是说,珠宝的价值分别为 2,3,…,n+1

华生挑战夏洛克,让他给这些珠宝染色,使得一件珠宝的价格是另一件珠宝的价格的质因子时,两件珠宝的颜色不同

并且,华生要求他 使用的颜色数尽可能少

请帮助夏洛克完成这个简单的任务。

输入格式 只有一行一个整数 n,表示珠宝件数。

输出格式 第一行一个整数 k,表示所使用的颜色数;

第二行 n 个整数,表示第 1 到第 n 件珠宝被染成的颜色。

若有多种答案,输出任意一种。

请用 1k 表示你用到的颜色。

数据范围 1≤n≤10^5

输入样例1

3

输出样例1

2
1 1 2

输入样例2

4

输出样例2

2
2 1 1 2

二、解题思路

质数之间彼此互质没有连边,合数之间不满足题意也没有连边,只有质数向合数连边,显然构成了二分图,二分图当然2种颜色就可以了。

理解一下样例吧:

//输入
3
//输出
2
1 1 2

表示2~ 3~ 4三个数,质数,质数,合数,质数输出1,合数输出2

//输入
4
//输出
2
1 1 2 1

表示 2~3~4~5 , 这里题目给出的答案与我输出的不一样,yxc说有多组答案都可以的时候,后台用special~judge进行判断,也是可以的。

注意:当n<=2时只有质数,输出1,由二分图可知其他情况均为2

三、实现代码

#include <bits/stdc++.h>
using namespace std;

// 欧拉筛
const int N = 1e5 + 10;
int primes[N], cnt; // primes[]存储所有素数
bool st[N];         // st[x]存储x是否被筛掉
void get_primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!st[i]) primes[cnt++] = i;
        for (int j = 0; primes[j] * i <= n; j++) {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

int main() {
    // 加快读入
    ios::sync_with_stdio(false), cin.tie(0);
    // 筛出区间内所有质数
    get_primes(N - 1);

    int n;
    cin >> n;
    // 1、质数与质数之间没有边
    // 2、合数可以由它的质因子连边那么合数与合数之间就是没有边
    // 根据上面的性质这就是一个由质数集合与合数集合构成的一个二分图根据二分图染色办法知道只需要1~2种颜色即可
    n <= 2 ? puts("1") : puts("2"); // n=3时价值就会出现4就是有合数出现这时就是二分图而且中间有边连接了

    for (int i = 2; i <= n + 1; i++)
        !st[i] ? printf("1 ") : printf("2 "); // 没有被筛掉的话是质数输出1否则合数输出2

    return 0;
}