【Codeforces 558C】Amr and Chemistry (二进制)

Amr and Chemistry (枚举&二进制)

  • 时间 : 2019年03月25日
  • 作者 : 数字_ID

题意

给你一些数,你只能 ∗ 2 * 2 2 或者 ÷ 2 \div2 ÷2(向下取整),让你用最小的次数实现让每个数都相等,并输出最小次数

题解

  1. 首先把所有数全部左移到最高
  2. 通过同或得到公共的01串
  3. 枚举这个01串后面0的个数的所有可能,暴力地去计算所有代价

代码

#include <stdio.h>
#include <map>
#include <utility>
#include <functional>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <string>
#include <string.h>
#include <stack>
#include <set>
#include <math.h>

#define lowbit(x) (x & (-x) )
#define ul unsigned int

using namespace std;
ul arr[100020];
ul num[100020];
ul brr[100020];
ul get_cnt(ul now)
{
	ul cnt = 0;
	while(now){
		cnt ++;
		now = now & (now - 1);
	}
	return cnt;
}

int  main()
{
	ul n;
	cin >> n;
	for(ul i = 0;i<n;i++)cin >> arr[i];
	for(ul i = 0;i<n;i++){
		brr[i] = arr[i] << ((31-(ul)log2(arr[i])));
	}

	for(ul i = 0;i<n;i++)num[i] = get_cnt(arr[i]);
	ul temp = (ul)((1ll << 32) - 1ll);
	for(ul i = 1;i<n;i++){
		ul res = ~(brr[0] ^ brr[i]);	
		temp = temp & res;
	}
	temp = brr[0] & temp;
	ul f_cnt = get_cnt(temp);

	ul st = log2(lowbit(temp));
	//cout << st << endl;
	ul mn = 0x3f3f3f3f;
	for(ul i = 0;i <= st;i++)
	{
		ul now = temp >> i;
		//cout << now << endl;
		ul cst = 0;
		for(ul j = 0;j<n;j++){
			ul nn = arr[j];
			
			if((ul)log2(now) >  (ul)log2(arr[j])){
				while(f_cnt < get_cnt(nn)){
					//cout << "fuck" << endl;
					cst ++;	
					nn >>= 1;
				}
				while(now > nn){
					cst ++;
					nn <<= 1;
				}
			}else{
				while(f_cnt < get_cnt(nn)){
					cst ++;	
					nn >>= 1;
				}
				while(nn < now){
					cst++;
					nn <<= 1;
				}
				while(nn > now){
					cst ++;
					nn >>= 1;
				}
				
			}
		}
		mn = min(mn , cst);
	}
	cout << mn << endl;
	return 0;	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值