Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

จำนวนการลบน้อยที่สุดจากอาร์เรย์เพื่อให้ GCD เพิ่มขึ้นใน Python

ลบสมาชิกน้อยที่สุดเพื่อเพิ่ม GCD ของอาร์เรย์

กำหนดอาร์เรย์ N ตัวเลข ต้องการหาจำนวนสมาชิกที่ต้องลบน้อยที่สุด เพื่อให้ GCD ของสมาชิกที่เหลือ มากกว่า GCD เดิมของอาร์เรย์ทั้งหมด

ตัวอย่าง: [6, 9, 15, 30] → GCD เดิม = 3 ลบ 6, 9 เหลือ [15, 30] GCD = 15 > 3 → ลบ 2 ตัว

แนวคิดหลัก

  1. คำนวณ GCD ทั้งอาร์เรย์ เรียกว่า g
  2. หารทุกสมาชิกด้วย g → ได้อาร์เรย์ใหม่ที่ GCD = 1
  3. แยกตัวประกอบเฉพาะของแต่ละสมาชิก (ใช้ Sieve สำหรับหา SPF - Smallest Prime Factor)
  4. นับความถี่ของแต่ละเฉพาะที่ปรากฏในอาร์เรย์
  5. เฉพาะที่ปรากฏบ่อยที่สุด → เก็บสมาชิกที่มีเฉพาะนั้นไว้ ลบอีกส่วน → ได้ GCD ใหม่ที่มากกว่าเดิม
  6. คำตอบ = N - max_frequency

โค้ดตัวอย่าง Python

from math import gcd as __gcd

INF = 100001
spf = [i for i in range(INF)]

def sieve():
    for i in range(4, INF, 2):
        spf[i] = 2
    for i in range(3, INF):
        if i * i > INF:
            break
        if spf[i] == i:
            for j in range(2 * i, INF, i):
                if spf[j] == j:
                    spf[j] = i

def calc_fact(x):
    ret = []
    while x != 1:
        ret.append(spf[x])
        x //= spf[x]
    return ret

def minRemove(a, n):
    g = 0
    for i in range(n):
        g = __gcd(a[i], g)
    my_map = {}
    for i in range(n):
        a[i] //= g
    for i in range(n):
        p = calc_fact(a[i])
        s = set(p)
        for prime in s:
            my_map[prime] = my_map.get(prime, 0) + 1
    minimum = 10**9
    for prime, cnt in my_map.items():
        if (n - cnt) <= minimum:
            minimum = n - cnt
    return minimum if minimum != 10**9 else -1

# ตัวอย่าง
a = [6, 9, 15, 30]
sieve()
print(minRemove(a, len(a)))  # 2