A题,考试的时候花了90min左右终于想出一个接近正解的办法(而然大佬都是一眼扫出结果),发现每个数分解都是log(n)完成并且有效的子因子始终只有两个,所以可以开map记录每个数分解的情况,
/* A - 木棍 */
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 51;
int n, a[MAXN], anss = MAXN * 30;
struct rec
{
int num, sum;
};
map<int, int> ans, mp;
priority_queue<rec> q;
bool operator<(const rec &a, const rec &b)
{
return a.sum > b.sum;
}
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = (ch == '-') ? -1 : 1, ch = getchar();
while (isdigit(ch))
x = x * 10 + (ch - '0'), ch = getchar();
return x * f;
}
void bfs(int now, int i)
{
rec x;
x.num = now;
x.sum = 1;
q.push(x);
while (!q.empty())
{
x = q.top();
q.pop();
if (mp[(x.num)] != 0)
continue;
mp[x.num] = x.sum;
if (x.num == 1)
continue;
if (x.num % 2 == 0)
q.push((rec){x.num / 2, x.sum + 1});
else
q.push((rec){x.num / 2, x.sum + 1}), q.push((rec){x.num / 2 + 1, x.sum + 1});
}
map<int, int>::iterator iter;
for (iter = mp.begin(); iter != mp.end(); iter++)
{
if (ans[iter->first] == 0 && i != 1)
mp[iter->first] = 0;
else
mp[iter->first] += ans[iter->first];
}
ans.clear();
for (iter = mp.begin(); iter != mp.end(); iter++)
if (iter->second != 0)
ans[iter->first] = iter->second /*,printf("%d %d\n",iter->first,iter->second)*/;
}
main()
{
n = read();
;
for (int i = 1; i <= n; ++i)
{
a[i] = read();
mp.clear();
bfs(a[i], i);
}
map<int, int>::iterator it;
for (it = ans.begin(); it != ans.end(); it++)
anss = min(anss, it->second);
printf("%d", anss - n);
return 0;
}