1 条题解
-
0
方法思路
- 核心思想:枚举每个账号作为特殊账号(贡献ai粉丝),其余账号贡献⌊ai/2⌋粉丝
- 算法步骤:
- 尝试每个账号作为特殊账号
- 如果特殊账号粉丝数恰好为x,直接返回1
- 否则,贪心选择其他账号(按贡献值从大到小)直到恰好达到目标x
- 同时考虑不使用特殊账号的情况
- 取所有可行方案中使用账号数最少的方案
- 贪心策略:固定特殊账号后,优先选择贡献值大的普通账号,以最小化总账号数
代码实现
Java
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int x = scanner.nextInt(); int[] fans = new int[n]; for (int i = 0; i < n; i++) { fans[i] = scanner.nextInt(); } System.out.println(minAccounts(n, x, fans)); scanner.close(); } private static int minAccounts(int n, int x, int[] fans) { int minCount = Integer.MAX_VALUE; // 尝试每个账号作为特殊账号 for (int i = 0; i < n; i++) { int special = fans[i]; // 特殊账号的全部粉丝数 // 如果特殊账号恰好满足需求 if (special == x) { return 1; } // 如果特殊账号不够,需要其他账号辅助 if (special < x) { // 计算还需要的粉丝数 int need = x - special; // 其他账号的贡献(每个贡献ai/2) List<Integer> others = new ArrayList<>(); for (int j = 0; j < n; j++) { if (j != i) { others.add(fans[j] / 2); } } // 按贡献从大到小排序 Collections.sort(others, Collections.reverseOrder()); // 贪心选择其他账号 int count = 1; // 已经选择了特殊账号 int total = 0; for (int contrib : others) { if (total + contrib <= need) { total += contrib; count++; if (total == need) { // 恰好满足 minCount = Math.min(minCount, count); break; } } } } } // 尝试不使用特殊账号,所有账号都贡献ai/2 List<Integer> contributions = new ArrayList<>(); for (int f : fans) { contributions.add(f / 2); } Collections.sort(contributions, Collections.reverseOrder()); int total = 0; int count = 0; for (int contrib : contributions) { total += contrib; count++; if (total == x) { // 恰好满足 minCount = Math.min(minCount, count); break; } if (total > x) { // 超过了,不可能恰好满足 break; } } return minCount != Integer.MAX_VALUE ? minCount : -1; } }
Python
def min_accounts(n, x, fans): # 尝试使用特殊账号(贡献全部粉丝) min_count = float('inf') # 尝试每个账号作为特殊账号 for i in range(n): special = fans[i] # 特殊账号的全部粉丝数 # 如果特殊账号恰好满足需求 if special == x: return 1 # 如果特殊账号不够,需要其他账号辅助 if special < x: # 计算还需要的粉丝数 need = x - special # 其他账号的贡献(每个贡献ai/2) others = [] for j in range(n): if j != i: others.append(fans[j] // 2) # 按贡献从大到小排序 others.sort(reverse=True) # 贪心选择其他账号 count = 1 # 已经选择了特殊账号 total = 0 for contrib in others: if total + contrib <= need: total += contrib count += 1 if total == need: # 恰好满足 min_count = min(min_count, count) break # 尝试不使用特殊账号,所有账号都贡献ai/2 contributions = [f // 2 for f in fans] contributions.sort(reverse=True) total = 0 count = 0 for contrib in contributions: total += contrib count += 1 if total == x: # 恰好满足 min_count = min(min_count, count) break return min_count if min_count != float('inf') else -1 # 读取输入 n, x = map(int, input().split()) fans = list(map(int, input().split())) # 输出结果 print(min_accounts(n, x, fans))
C++
#include <iostream> #include <vector> #include <algorithm> #include <climits> using namespace std; int minAccounts(int n, int x, vector<int>& fans) { int minCount = INT_MAX; // 尝试每个账号作为特殊账号 for (int i = 0; i < n; i++) { int special = fans[i]; // 特殊账号的全部粉丝数 // 如果特殊账号恰好满足需求 if (special == x) { return 1; } // 如果特殊账号不够,需要其他账号辅助 if (special < x) { // 计算还需要的粉丝数 int need = x - special; // 其他账号的贡献(每个贡献ai/2) vector<int> others; for (int j = 0; j < n; j++) { if (j != i) { others.push_back(fans[j] / 2); } } // 按贡献从大到小排序 sort(others.begin(), others.end(), greater<int>()); // 贪心选择其他账号 int count = 1; // 已经选择了特殊账号 int total = 0; for (int contrib : others) { if (total + contrib <= need) { total += contrib; count++; if (total == need) { // 恰好满足 minCount = min(minCount, count); break; } } } } } // 尝试不使用特殊账号,所有账号都贡献ai/2 vector<int> contributions; for (int f : fans) { contributions.push_back(f / 2); } sort(contributions.begin(), contributions.end(), greater<int>()); int total = 0; int count = 0; for (int contrib : contributions) { total += contrib; count++; if (total == x) { // 恰好满足 minCount = min(minCount, count); break; } if (total > x) { // 超过了,不可能恰好满足 break; } } return minCount != INT_MAX ? minCount : -1; } int main() { int n, x; cin >> n >> x; vector<int> fans(n); for (int i = 0; i < n; i++) { cin >> fans[i]; } cout << minAccounts(n, x, fans) << endl; return 0; }
- 1
信息
- ID
- 44
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者