CF #582 Div.3 D - Equalizing by Division (暴力 枚举)

给出n个数, 你可以对任意一个数进行数次 除以 2 的操作直到为0, 给出一个整数m, 求 要使 n 个数中 有 m 个数相同, 至少操作几次。

好暴力,, 枚举出n个数中每个数除以2直到为0的所有数, 找出一个数 t   使n个数中的m个数变为t所需操作数最少。 

最大值为 2*1e5 所以开一个这么大的vector就够了.

然后为了得到  某个 数  n  变为 t 所需的最少操作步骤,我们需要从小到大依次枚举, 这样 t 第一次出现时,一定是 n 变为 t 所需的最少操作数, 因为数组经过排序后是递增的。

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; 
vector <int> A[2*100005];
int main(){
	int n, s;
	cin>>n>>s;
	int arr[2*100005];
	for(int i = 0; i < n; i++){
			cin>>arr[i];
	}
	sort(arr,arr+n);
	for(int i = 0; i < n; i++){
		int t = arr[i];
		int step = 0;
		A[t].push_back(step++);
		while(t){
			t>>=1;
			A[t].push_back(step++); // 因为数组排序后是上升的的,所以t第一次出现的步数就是最小步数,  
		}
	}
	int Min = 9999999;
	for(int i = 0; i <= 2*100000; i++){
		if(A[i].size() < s) continue; //  A[i].size 代表的是 i 出现了几次。 每一个A[i][j] 是得到 i 需要的最小步数  
		int ans = 0; 
		for(int j = 0; j < s ; j++){ // 取 最小的 s 个  
			ans += A[i][j];
			if(ans > Min) break;
		} 
		if(Min > ans) Min = ans;
	}
	cout<<Min<<endl;
	return 0;
}
发布了52 篇原创文章 · 获赞 114 · 访问量 6016

猜你喜欢

转载自blog.csdn.net/GD_ONE/article/details/101001059
今日推荐