【题目描述】
The only difference between easy and hard versions is the number of elements in the array.You are given an array a consisting of n integers. In one move you can choose any ai and divide it by 2 rounding down (in other words, in one move you can set ai:=⌊ai2⌋).You can perform such an operation any (possibly, zero) number of times with any ai.Your task is to calculate the minimum possible number of operations required to obtain at least k equal numbers in the array.Don't forget that it is possible to have ai=0 after some operations, thus the answer always exists.InputThe first line of the input contains two integers n and k (1≤k≤n≤50) — the number of elements in the array and the number of equal numbers required.The second line of the input contains n integers a1,a2,…,an (1≤ai≤2⋅105), where ai is the i-th element of a.OutputPrint one integer — the minimum possible number of operations required to obtain at least k equal numbers in the array.ExamplesInput
5 3
1 2 2 4 5
Output
1
Input
5 3
1 2 3 4 5
Output
2
Input
5 3
1 2 3 3 3
Output
0
【题目分析】
敢想不敢做系列,总觉得是一个贪心或者什么的,但是没有想到什么好的策略。暴力吧又不敢写,105的数据暴力,emmm。
在网上查了一下题解,发现还真是一个暴力,只不过这种暴力的思想我还是没有想到,主要是人家用到vector开二维数组,我觉得肯定会爆空间就没想到用二维数组。
用一个二维数组vis[i][j]vis[i][j]vis[i][j]j变成i需要多少步,这样我们找到含有k个以上数字可以变成他的vis[i]然后找需要步数最小的。不明白可以看代码,很暴力的做法。
我把看的题解的代码稍微改动了一下,稍微进行了优化,首先,我将整个数组进行排序,然后按照这个顺序建立的二维数组肯定是有序的,对于每个i,肯定是j越小所用步数越小的在前面,这样就不用每个都进行排序了(竟然排序都能过)。还有就是加上了一个剪枝,如果当前步数已经大于前面找到的答案直接退出。
还是要敢想敢做啊,不要被复杂度蒙蔽了双眼什么都不敢做。就算TLE了也比什么都做不出来强。(当然如果是DP然后还想暴力那就emmm了)
【AC代码】
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<set>
#include<map>
#include<vector>using namespace std;typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=2e5+5;
vector<int> vis[MAXN];
int a[MAXN];
int n,k,ans;int main()
{int t,step,tmp;scanf("%d%d",&n,&k);for(int i=0;i<n;i++){scanf("%d",&a[i]);}sort(a,a+n);for(int i=0;i<n;i++){t=a[i];step=0;vis[t].push_back(step++);while(t){t>>=1;//先除2,这样可以将0也计算进去vis[t].push_back(step++);}}ans=INT_MAX;for(int i=0;i<MAXN;i++){if(vis[i].size()<k) continue;tmp=0;for(int j=0;j<k;j++){tmp+=vis[i][j];if(tmp>ans) break;}if(tmp<ans) ans=tmp;}printf("%d",ans);return 0;
}