cf#582div3 D——暴力

【题目描述】

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.

Input

The 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.

Output

Print one integer — the minimum possible number of operations required to obtain at least k equal numbers in the array.

Examples

Input
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开二维数组,我觉得肯定会爆空间就没想到用二维数组。
用一个二维数组 v i s [ 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值