1293 夏洛克和他的girl friend(二分图、线性筛)

1. 问题描述:

夏洛克有了一个新女友(这太不像他了!)。情人节到了,他想送给女友一些珠宝当做礼物。他买了 n 件珠宝,第 i 件的价值是 i+1,也就是说,珠宝的价值分别为 2,3,…,n+1。华生挑战夏洛克,让他给这些珠宝染色,使得一件珠宝的价格是另一件珠宝的价格的质因子时,两件珠宝的颜色不同。并且,华生要求他使用的颜色数尽可能少。请帮助夏洛克完成这个简单的任务。

输入格式

只有一行一个整数 n,表示珠宝件数。

输出格式

第一行一个整数 k,表示所使用的颜色数;第二行 n 个整数,表示第 1 到第 n 件珠宝被染成的颜色。若有多种答案,输出任意一种。请用 1 到 k 表示你用到的颜色。

数据范围

1 ≤ n ≤ 10 ^ 5

输入样例1:
3
输出样例1:
2
1 1 2
输入样例2:
4
输出样例2:
2
2 1 1 2
来源:https://www.acwing.com/problem/content/description/1295/

2. 思路分析:

分析题目可以知道一开始比较容易想到的应该是图论方面的问题,一个数是另外一个数的质因子可以看成某个质数向另外一个合数连一条边,但是直接这样做可以发现很难解决,所以我们需要挖掘一下题目的特殊性,可以发现都是质数向合数连一条边,所以整个图是一个二分图(得到这一点其实很重要),我们可以将2~n+1的数字分成两类,左边为质数,右边为合数,质数与合数分别染成不同的颜色即可,所以答案小于等于2,由于题目中至少一个数字所以答案不可能为0,所以答案只能为1或者2,什么时候为1呢?可以发现当没有合数的时候答案就为1,此时二分图中是没有任何边的,n = 1,x = 2;n = 2,x = 2,3,n = 3,x = 2,3,4,n = 3的时候就有合数了,所以当n <= 2时答案为1,当n >= 3时答案为2,然后使用线性筛法法标记所有的质数,将质数和合数分别染成不同的颜色即可,代码不是特别难,主要是中间的分析过程比较有难度。

3. 代码如下:

from typing import List


class Solution:
    # 线性筛
    def init(self, n: int, primes: List[int], st: List[int]):
        count = 0
        for i in range(2, n):
            if st[i] == 0:
                primes[count] = i
                count += 1
            j = 0
            while primes[j] * i < n:
                st[primes[j] * i] = 1
                if i % primes[j] == 0:
                    break
                j += 1

    def process(self):
        n = int(input())
        primes, st = [0] * (n + 10), [0] * (n + 10)
        self.init(n + 10, primes, st)
        if n <= 2: print(1)
        else: print(2)
        # 是质数输出1否则输出2
        for i in range(2, n + 2):
            if st[i] == 0:
                print(1, end=" ")
            else:
                print(2, end=" ")
        print()


if __name__ == '__main__':
    Solution().process()

猜你喜欢

转载自blog.csdn.net/qq_39445165/article/details/121876947
今日推荐