题面:
题意:
给定一个序列,你可以进行一下两种操作:
1、复制一遍当前序列
2、选择当前序列与其他序列(包括自身)中各一个元素进行交换
问:最少需要多少次操作才能使序列里的元素全部相同。
题解:
从贪心的思想来看,肯定得以原序列里出现次数最多的元素为目标来构造答案序列最为简便。此外,操作 1 和操作 2 综合起来看实际上就是对原序列里目标元素进行翻倍,那么问题就很简单了。
代码:
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define eps 1e-10
#define lowbit(x) x&-x
#define int long long
int T,n;
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
cin>>T;
while(T--)
{
cin>>n;
map<int,int> m;
vector<int> a(n+1);
int MAX=0,t,ans=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
m[a[i]]++;
if(m[a[i]]>MAX)
{
//找出出现次数最多的元素
MAX=m[a[i]];
t=a[i];
}
}
int acc=m[t];
if(acc==n)
{
//特判
cout<<0<<endl;
continue;
}
for(int i=acc;i<=n;i*=2)
{
ans++;//复制一次
if(n-acc<=i)
{
//多了就看只需要多少
ans+=n-acc;
break;
}
//足够就全换
ans+=i;
acc+=i;
}
cout<<ans<<endl;
}
return 0;
}