step1:创建一个字典map,其key表示数组中的元素,value表示该元素在数组中出现的个数。我们维护所有key中的最小值minK。
step2:由于map底层是红黑树,其key是按照从小到大排列的,因此我们很容易获得其最大的key。对这个key,先将其从map中移除,然后对该key值进行二进制右移的操作(即题目中的除以2向下取整),每一次操作,实际的操作数为key对应的value。经过若干次操作,直到key的值小于等于minK。此时将新的键值对key-value更新到map中。
step3:重复step2,直到map中只剩下一个key-value为止。
#include <iostream> #include <map> using namespace std; int main() { int n, a, minK = INT32_MAX; cin >> n; map<int, int> mp; for (int i = 0; i < n; ++i) { cin >> a; ++mp[a]; minK = min(minK, a); } int ans = 0; while (mp[minK] != n) { auto kv = *mp.rbegin(); int key = kv.first; int value = kv.second; mp.erase(key); while (key > minK) { key >>= 1; ans += value; } mp[key] += value; minK = min(minK, key); } cout << ans; }