1 条题解
-
0
方法思路
- 经过数学分析,我们可以得出以下结论:
- 数组总和不变(每次操作一个+2,一个-2)
- 每个元素的奇偶性不变
- 要使GCD为素数,该素数必须是数组总和的因子
- 如果数组全是偶数,唯一的答案是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
- 上传者