1 solutions

  • 2
    @ 2026-6-9 17:14:21

    67要拿🏀杯国一,你们知道吗?

    结论

    • n=1n = 1nn 是质数,答案为 11
    • nn 是合数,答案为 n/2\lfloor n/2 \rfloor

    分析

    1. n=1n = 1

    无法进行任何拆分,直接返回 11

    2. nn 是质数

    假设存在拆分 n=y+zn = y + zgcd(y,z)>1\gcd(y, z) > 1。设 d=gcd(y,z)>1d = \gcd(y, z) > 1,则 y=day = d \cdot az=dbz = d \cdot b,且 a+b=n/da + b = n/d。因为 nn 是质数且 d>1d > 1,所以 d=nd = n,于是 a+b=1a + b = 1,与 a,b1a, b \ge 1 矛盾。因此质数无法拆分。

    3. nn 是合数(n4n \ge 4

    偶数合数:设 n=2kn = 2k。每次拆出 222k2+(2k2)2k \to 2 + (2k-2)gcd(2,2k2)=2>1\gcd(2, 2k-2) = 2 > 1。最终得到 kk22,答案为 n/2n/2

    奇数合数:设 n=2k+1n = 2k+1n9n \ge 9。目标是构造 1133k1k-122

    • 如果 nn33 的倍数,拆 n=3+(n3)n = 3 + (n-3)n3n-3 是偶数全拆成 22

    • 否则设 ppnn 的最小奇质因子(n=pmn = p \cdot mp5p \ge 5),拆 n=3p+p(m3)n = 3p + p(m-3)

      • 3p3p33 的倍数,拆成 33 + 一堆 22
      • p(m3)p(m-3)m3m-3 是偶数,所以这部分全是偶数,全拆成 22

    举例(n=49n = 49

    49=7×749 = 7 \times 7,不是 33 的倍数,最小奇质因子 p=7p = 7m=7m = 7

    第一步:49=3×7+7×(73)=21+2849 = 3 \times 7 + 7 \times (7-3) = 21 + 28

    • 212133 的倍数:21=3+1821 = 3 + 181818 是偶数 → 9922,加上 1133,共 1010 个元素
    • 2828 是偶数:全拆成 141422

    最终:1133 + 9922 + 141422 = 2424 个元素 = 49/2\lfloor 49/2 \rfloor

    最终答案为 n/2\lfloor n/2 \rfloor

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    vector<int> sieve_primes(int limit) {
        vector<bool> is_prime(limit + 1, true);
        vector<int> primes;
        is_prime[0] = is_prime[1] = false;
        for (int i = 2; i <= limit; ++i) {
            if (is_prime[i]) primes.push_back(i);
            for (int p : primes) {
                if (1LL * i * p > limit) break;
                is_prime[i * p] = false;
                if (i % p == 0) break;
            }
        }
        return primes;
    }
    
    bool is_prime(int n, const vector<int>& primes) {
        if (n < 2) return false;
        for (int p : primes) {
            if (1LL * p * p > n) break;
            if (n % p == 0) return false;
        }
        return true;
    }
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
        vector<int> primes = sieve_primes(31623);
        int T;
        cin >> T;
        while (T--) {
            int n;
            cin >> n;
            if (n == 1) cout << 1 << '\n';
            else if (is_prime(n, primes)) cout << 1 << '\n';
            else cout << n / 2 << '\n';
        }
        return 0;
    }
    

    Information

    ID
    3
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    4
    Tags
    # Submissions
    41
    Accepted
    8
    Uploaded By