1 solutions

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

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

    结论

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

    分析

    1. n=1n = 1

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

    2. nn 是质数

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

    3. nn 是合数(n≥4n \ge 4)

    偶数合数:设 n=2kn = 2k。每次拆出 22:2k→2+(2k−2)2k \to 2 + (2k-2),gcd⁡(2,2k−2)=2>1\gcd(2, 2k-2) = 2 > 1。最终得到 kk 个 22,答案为 n/2n/2。

    奇数合数:设 n=2k+1n = 2k+1 且 n≥9n \ge 9。目标是构造 11 个 33 和 k−1k-1 个 22。

    • 如果 nn 是 33 的倍数,拆 n=3+(n−3)n = 3 + (n-3),n−3n-3 是偶数全拆成 22。

    • 否则设 pp 是 nn 的最小奇质因子(n=p⋅mn = p \cdot m,p≥5p \ge 5),拆 n=3p+p(m−3)n = 3p + p(m-3):

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

    举例(n=49n = 49):

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

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

    • 2121 是 33 的倍数:21=3+1821 = 3 + 18,1818 是偶数 → 99 个 22,加上 11 个 33,共 1010 个元素
    • 2828 是偶数:全拆成 1414 个 22

    最终:11 个 33 + 99 个 22 + 1414 个 22 = 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
    44
    Accepted
    9
    Uploaded By