一、标题
小A的魔法符文I
二、题目描述
在一个神秘的魔法学院中,小A是一位独特的魔法学徒,专注于创造独一无二的魔法符文。他的作品集中包括n个魔法符文,每个符文都有其对应的魔法特征值。然而,小A对于使用相同的魔法特征值符文感到厌倦,于是他特地学习了一门符文融合术,想要通过融合不同的魔法符文来改变符文的特征值,确保每个符文都有其独特的魔法属性。
符文融合术的规则具体如下,小A每次可以选择两个符文,它们的魔法特征值分别为x和y,对其施展魔法后,可以将其变成特征值为x和x+y的符文。现在小A想知道,他最少需要进行多少次融合,才能确保整个符文集的魔法特征值互不相同。
这个神秘的魔法学院注定会见证一场独特的魔法融合之旅。你能设计一个算法,帮助小A完成这个神奇的任务吗?
三、输入
第一行输入一个正整数n,表示小A所拥有的符文个数。
接下来一行输入n个数字Ci分别表示每个魔法符文的魔法特征值。
对于所有数据,0 < n <= 100000,1 <= Ci <= n。
四、输出
输出一个非负整数表示最小融合次数。
五、样例输入
6
1 2 1 5 4 5
六、样例输出
2
七、提示
经过两次符文融合术,可以得到下面不同的魔法特征值符文
1 2 3 10 4 5
八、分析
基本思路是让重复的魔法特征值加上当前最大的魔法特征值,可以得到不会和其他数重复的新最大魔法特征值,对每个重复的数都这样处理,对于每种重复魔法特征值融合的次数就是重复数减一,因此总融合次数就是上述融合次数的和。
可以令数组下标与魔法特征值对应,先初始化数组内所有元素为0,,然后每读一个魔法符文的魔法特征值,就查一次这个值对应下标的数组里的值是否为0,然后把那个数对应数组位置的值从0改成1(或累加),否则计数加1,这样边读边计数可以提供相对较低的时间复杂度,读入所有魔法符文的魔法特征值后即统计出最小融合次数。
九、代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, cnt = 0, num[100001] = {0};
cin >> n;
for (int i = 1, j; i <= n; i++) {
cin >> j;
if (num[j] == 0) {
num[j]++;
} else {
cnt++;
}
}
cout << cnt << endl;
return 0;
}