1 条题解

  • 0
    @ 2025-7-14 17:30:17

    方法思路

    1. 经过数学分析,我们可以得出以下结论:
      • 数组总和不变(每次操作一个+2,一个-2)
      • 每个元素的奇偶性不变
      • 要使GCD为素数,该素数必须是数组总和的因子
      • 如果数组全是偶数,唯一的答案是2
      • 如果数组包含奇数,答案不可能是2
    2. 具体做法:
      • 计算数组总和sum和平均值avg
      • 对于数组全是偶数的情况,输出2
      • 对于有奇数的情况,枚举sum的所有素因子p(p <= avg)
      • 验证每个素因子是否可行:奇数可以变成p的奇数倍,偶数可以变成p的偶数倍

    代码实现

    Java
    import java.io.*;
    import java.util.*;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            int n = Integer.parseInt(br.readLine());
            String[] tokens = br.readLine().split(" ");
            
            int[] arr = new int[n];
            long sum = 0;
            boolean hasOdd = false;
            boolean allEven = true;
            
            for (int i = 0; i < n; i++) {
                arr[i] = Integer.parseInt(tokens[i]);
                sum += arr[i];
                if (arr[i] % 2 != 0) {
                    hasOdd = true;
                    allEven = false;
                }
            }
            
            List<Integer> result = new ArrayList<>();
            
            // 情况1:全是偶数,答案只有2
            if (allEven) {
                result.add(2);
            } 
            // 情况2:有奇数,枚举sum的素因子
            else if (hasOdd) {
                int avg = (int)(sum / n);
                
                // 找出sum的所有素因子(不超过avg)
                List<Integer> primeFactors = findPrimeFactorsUpTo(sum, avg);
                
                for (int p : primeFactors) {
                    if (p == 2) continue; // 有奇数时,2不可能是答案
                    
                    boolean possible = true;
                    for (int num : arr) {
                        // 奇数只能变成p的奇数倍,偶数只能变成p的偶数倍
                        if (num % 2 != 0 && p % 2 == 0) {
                            possible = false;
                            break;
                        }
                    }
                    
                    if (possible) {
                        result.add(p);
                    }
                }
            }
            
            if (result.isEmpty()) {
                System.out.println("NO");
            } else {
                System.out.println("YES");
                Collections.sort(result);
                StringBuilder sb = new StringBuilder();
                for (int p : result) {
                    sb.append(p).append(" ");
                }
                System.out.println(sb.toString().trim());
            }
        }
        
        // 找出n的所有素因子,但不超过maxValue
        private static List<Integer> findPrimeFactorsUpTo(long n, int maxValue) {
            List<Integer> factors = new ArrayList<>();
            
            // 处理2
            if (n % 2 == 0 && 2 <= maxValue) {
                factors.add(2);
                while (n % 2 == 0) n /= 2;
            }
            
            // 处理奇数素因子
            for (int i = 3; i <= Math.min(maxValue, (int)Math.sqrt(n)); i += 2) {
                if (n % i == 0) {
                    factors.add(i);
                    while (n % i == 0) n /= i;
                }
            }
            
            // 如果n是素数且小于等于maxValue
            if (n > 2 && n <= maxValue) {
                factors.add((int)n);
            }
            
            return factors;
        }
    }
    
    
    Python
    def find_prime_factors_up_to(n, max_value):
        factors = []
        
        # 处理2
        if n % 2 == 0 and 2 <= max_value:
            factors.append(2)
            while n % 2 == 0:
                n //= 2
        
        # 处理奇数素因子
        i = 3
        while i <= min(max_value, int(n**0.5)):
            if n % i == 0:
                factors.append(i)
                while n % i == 0:
                    n //= i
            i += 2
        
        # 如果n是素数且小于等于max_value
        if n > 2 and n <= max_value:
            factors.append(int(n))
        
        return factors
    
    n = int(input())
    arr = list(map(int, input().split()))
    
    # 计算总和和平均值
    total_sum = sum(arr)
    avg = total_sum // n
    
    # 检查是否所有数都是偶数
    all_even = all(num % 2 == 0 for num in arr)
    has_odd = any(num % 2 != 0 for num in arr)
    
    result = []
    
    # 情况1:全是偶数,答案只有2
    if all_even:
        result.append(2)
    # 情况2:有奇数,枚举素因子
    elif has_odd:
        prime_factors = find_prime_factors_up_to(total_sum, avg)
        
        for p in prime_factors:
            if p == 2:  # 有奇数时,2不可能是答案
                continue
                
            possible = True
            for num in arr:
                # 奇数只能变成p的奇数倍,偶数只能变成p的偶数倍
                if num % 2 != 0 and p % 2 == 0:
                    possible = False
                    break
                    
            if possible:
                result.append(p)
    
    if not result:
        print("NO")
    else:
        print("YES")
        print(*sorted(result))
    
    
    C++
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cmath> // 添加cmath头文件以使用sqrt函数
    using namespace std;
    
    // 找出n的所有素因子,但不超过maxValue
    vector<int> findPrimeFactorsUpTo(long long n, int maxValue) {
        vector<int> factors;
        
        // 处理2
        if (n % 2 == 0 && 2 <= maxValue) {
            factors.push_back(2);
            while (n % 2 == 0) n /= 2;
        }
        
        // 处理奇数素因子
        for (int i = 3; i <= min(maxValue, (int)sqrt(n)); i += 2) {
            if (n % i == 0) {
                factors.push_back(i);
                while (n % i == 0) n /= i;
            }
        }
        
        // 如果n是素数且小于等于maxValue
        if (n > 2 && n <= maxValue) {
            factors.push_back((int)n);
        }
        
        return factors;
    }
    
    int main() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        
        int n;
        cin >> n;
        
        vector<int> arr(n);
        long long sum = 0;
        bool hasOdd = false;
        bool allEven = true;
        
        for (int i = 0; i < n; i++) {
            cin >> arr[i];
            sum += arr[i];
            if (arr[i] % 2 != 0) {
                hasOdd = true;
                allEven = false;
            }
        }
        
        vector<int> result;
        int avg = sum / n;
        
        // 情况1:全是偶数,答案只有2
        if (allEven) {
            result.push_back(2);
        }
        // 情况2:有奇数,枚举素因子
        else if (hasOdd) {
            vector<int> primeFactors = findPrimeFactorsUpTo(sum, avg);
            
            for (int p : primeFactors) {
                if (p == 2) continue; // 有奇数时,2不可能是答案
                
                bool possible = true;
                for (int num : arr) {
                    // 奇数只能变成p的奇数倍,偶数只能变成p的偶数倍
                    if (num % 2 != 0 && p % 2 == 0) {
                        possible = false;
                        break;
                    }
                }
                
                if (possible) {
                    result.push_back(p);
                }
            }
        }
        
        if (result.empty()) {
            cout << "NO" << endl;
        } else {
            cout << "YES" << endl;
            sort(result.begin(), result.end());
            for (size_t i = 0; i < result.size(); i++) { // 使用size_t类型避免符号比较警告
                cout << result[i];
                if (i < result.size() - 1) cout << " ";
            }
            cout << endl;
        }
        
        return 0;
    }
    
    
    • 1

    信息

    ID
    66
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    1
    已通过
    1
    上传者