HJ28.素数伴侣

326 阅读2分钟

1. 题目

www.nowcoder.com/practice/b9…

image.png

2. 解析

2.1 判断一个数是否为素数:在这里需要注意的是全部数判断会超时,所以选择半位数来判断可以节省时间
2.2 判断最大匹配数: 一个列表里的数与另一个列表里的每一个数判断,如果他们的和是素数就标记,若这个数还有另一个匹配的数,则看看之前匹配的数是否还有其他匹配的数,有则这个数就被当前数替代,没有则跳过。如此一来得到的数即为最大匹配数
2.3 数的分配与具体判断实现:奇数和奇数相加与偶数和偶数相加得到的是偶数不可能是素数,只能是奇数和偶数相加才可能存在素数。因此将所有可匹配的数按奇数和偶数分为两个列表。然后让每一个奇数与所有偶数列表的数去匹配看相加的和是否为素数,如果是则加1

3. 核心代码

import math


def is_prime_num(x):
    # 判断是否为素数
    if x == 2:
        return True
    if x & 1 == 0:
        return False
    for i in range(3, int(math.sqrt(x)) + 1, 2):
        if x % i == 0:
            return False
    return True


def find_even(even, previous_select, final_select, o):
    # 奇数开始查找偶数
    for i, e in enumerate(even):
        if is_prime_num(e + o) and previous_select[i] == 0:
            previous_select[i] = 1
            # 判断第i位偶数是否被匹配或者他的匹配奇数是否还有其他选择,如果有其他选择,则当前的奇数匹配第i位偶数
            if final_select[i] == 0 or find_even(even, previous_select, final_select, final_select[i]):
                final_select[i] = o
                return True
    return False


def deal(n_lst):
    # 先区分奇偶数 只有奇数加偶数才有可能为素数
    odd = []
    even = []
    for i in n_lst:
        if i & 1 == 0:
            odd.append(i)
        else:
            even.append(i)
    count = 0
    final_select = [0] * len(even)
    for o in odd:
        previous_select = [0] * len(even)
        if find_even(even, previous_select, final_select, o):
            count += 1
    return count


def inp():
    n = int(input())
    n_lst = list(map(int, input().split(' ')))
    return deal(n_lst)

print(inp())