列表

详情


NC21671. 牛牛与木棍

描述

牛牛有一些木棍,现在牛牛想让这些木棍都变成同样的长度
牛牛可以进行如下的操作
选择一根长度为L>=2的木棍
如果L为偶数,将木棍一分为2,变成两根L/2的木棍
否则,分成一根为(L+1) / 2, 另一根为(L-1) / 2;
在分成的两根中选择其中一根,扔掉另外一根
牛牛的任务是让剩下的木棍变成一样长 ,现在请你帮助牛牛算出最少需要几步可以完成任务

输入描述

第一行输入一个整数n (2 ≤ n ≤ 50)

第二行输入n个整数表示每根木棍的长度ai (1 ≤ ai ≤ 109)

输出描述

输出一个整数

示例1

输入:

2
11 4

输出:

3

示例2

输入:

7
1 2 3 4 5 6 7

输出:

10

示例3

输入:

6
13 13 7 11 13 11

输出:

11

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 17ms, 内存消耗: 620K, 提交时间: 2020-06-14 19:18:35

#include<bits/stdc++.h>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 1e7 + 10;
int a[maxn];//,f[maxn];
unordered_map<int,int>mp,f;
int main()
{
	int n;
	queue<pair<int,int> >q;
	cin >> n;
	for(int i = 1;i <= n;i++)
	{
	scanf("%d",&a[i]), q.push({a[i],0});
	map<int,int>m;
	while(!q.empty())
	{
		pair <int,int> p;
		p = q.front();
		q.pop();
		if(m[p.first])continue;
	    m[p.first]++;
	    mp[p.first]++;
		f[p.first]+=p.second;
		q.push({(p.first)/2,p.second + 1});
		if(p.first%2) q.push({(p.first + 1)/2,p.second + 1});
	}
	while(!q.empty()) q.pop();
	}
	int ans = 1e8;
	for(auto it:mp)
	{
		if(it.second==n)
		{
			ans = min(ans,f[it.first]);
		}
	}
	cout << ans << endl;
	return 0;
}
//7 5
//6 3
//7 4
//5 3

C++11(clang++ 3.9) 解法, 执行用时: 7ms, 内存消耗: 520K, 提交时间: 2020-08-16 18:41:49

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int n;
map<int,int> cnt, mi;
int main(){
	scanf("%d", &n);
	for(int i=1;i<=n;i++) {
		int t;
		scanf("%d", &t);
		set<int> s;
		queue<pii> q;
		q.push(pii(t,0));
		while (q.size()) {
			pii u = q.front(); q.pop();
			if (s.count(u.x)) continue;
			s.insert(u.x);
			++cnt[u.x], mi[u.x] += u.y;
			q.push(pii(u.x/2,u.y+1));
			if (u.x%2) q.push(pii(u.x/2+1,u.y+1));
		}
	}
	int ans = 1e9;
	for (auto t:cnt) if (t.y==n) ans = min(ans, mi[t.x]);
printf("%d\n", ans);
}

上一题