给定一个长度为n的数组a=[a1,a2,…,an],一次操作可以选择数组中的一个数,然后将其移除,剩余元素保持原顺序依次拼接。希望经过若干次操作后,使得数组中所有非空子数组的平均值均相同。
子数组的定义为从原数组中连续选取的一段元素(可以全选也可以部分选)。
问题本质:
要使得一个数组中所有非空子数组的平均值均相同,必须要求数组中所有元素都相同。证明非常直观:
操作分析:
因此,题目要求我们通过删除操作将原数组中的元素调整为全相同的形式。
设选择使得剩余数组中所有元素均为x,则只需要保留原数组中所有值为x的元素,删除其它所有元素。
为使删除次数最少,我们应选择原数组中出现次数最多的那个数。
公式推导:
设数组长度为n,记某个数字的出现次数为f,最大出现次数为fmax。
则需要删除的最少次数为
#include <iostream>
#include <unordered_map>
#include <algorithm>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n; // 读入数组长度n
unordered_map<int, int> freq; // 用于统计每个数字出现次数的哈希表
int x;
int maxFreq = 0; // 记录最大频次
for (int i = 0; i < n; i++) {
cin >> x; // 读入数组元素a_i
freq[x]++;
maxFreq = max(maxFreq, freq[x]); // 更新最大频次
}
cout << n - maxFreq << "\n";
return 0;
}
# 读入数组长度n
n = int(input().strip())
# 读入数组元素,并转换成整数列表
a = list(map(int, input().split()))
# 使用字典统计每个数字出现的次数
freq = {}
maxFreq = 0 # 记录最大频次
for x in a:
if x in freq:
freq[x] += 1
else:
freq[x] = 1
maxFreq = max(maxFreq, freq[x]) # 更新最大频次
print(n - maxFreq)
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 读入数组长度n
// 使用 HashMap 统计每个数字的出现次数
HashMap<Integer, Integer> freq = new HashMap<>();
int maxFreq = 0; // 记录最大频次
for (int i = 0; i < n; i++) {
int x = sc.nextInt(); // 读入数组元素a_i
// 更新 HashMap 中数字x的出现次数
freq.put(x, freq.getOrDefault(x, 0) + 1);
maxFreq = Math.max(maxFreq, freq.get(x)); // 更新最大频次
}
sc.close();
System.out.println(n - maxFreq);
}
}
给定一个长度为 n 的数组 a ,定义一次操作
现在她想要知道,自己最少需要操作几次,才能使得数组中所有非空学数组的平均值均相同。
子数组为从原数组中,连续的选择一段元素(可以全选,可以不选)得到的新数组。
第一行输入一个整数n(1≦n≦2×105),表示数组长度。
第二行输入n个整数a1,a2,...,an(1≦ai≦109)代表数组。
一个整数,表示最少操作次数。
输入
3
1 2 3
输出
2
删除任意两个元素后,数组只剩下一个元素,此时只有一个非空子数组,一定满足题意。
输入
5
12111
输出
1
唯一的方案是将第二个元素删除。