有一个序列 a 长度为 n. 可以选择序列中两个数字 ai 和 aj (i != j, 1 <= i, j <= n) 如果 ai = aj 将其中一个数更改为 0. 否则,将它们都更改为它们之中最小的数。 需要将序列中的数字都更改为 0. 请你求出最小操作次数。 输入格式 第一行包含一个正整数 t (1 ≤ t ≤ 1000)表示测试用例的数量。 对于每组测试用例,第一行包含一个整数 n (2 ≤ n ≤ 100)表示序列 a 的长度. 第二行包含 n 个整数 a1,a2,...,an ( 0 ≤ ai ≤ 100). 输出格式 对于每组测试用例,打印一个整数表示将序列中的所有数字更改为 0 的最小操作次数。 输入样例 复制 3 3 1 2 3 3 1 2 2 3 1 2 0 输出样例 复制 4 3 2 c语言代码
时间: 2024-01-17 17:03:25 浏览: 324
根据题目描述,我们可以发现对于相同的两个数,将其中一个数改为 0 和将它们都改为最小值的操作次数是相同的,因为这两种操作都会让这两个数变成相同的数。
因此,我们可以先将所有相同的数都改为 0,这样操作次数就是相同数的个数。
然后,我们再统计序列中不同的数的个数,将它们都改为 0,这样操作次数就是相同数的个数加上不同数的个数。
以下是具体实现的 C++ 代码:
```cpp
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int a[N];
int main()
{
int T;
cin >> T;
while (T -- )
{
int n;
cin >> n;
memset(a, 0, sizeof a);
for (int i = 0; i < n; i ++ ) cin >> a[i];
sort(a, a + n);
int cnt = 0, distinct = 0;
for (int i = 0; i < n; i ++ )
{
if (a[i] == 0) cnt ++ ;
else
{
distinct ++ ;
if (i + 1 < n && a[i] == a[i + 1]) cnt ++ ;
}
}
cout << cnt + distinct << endl;
}
return 0;
}
```
时间复杂度:$O(Tn\log n)$
阅读全文